From 94d08bba62422d2e0beb44b157656aeeeef33ed2 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Sat, 30 Nov 2019 12:05:26 +0300 Subject: [PATCH] parse_name pn_getc --- dpx/src/dpx_dpxutil.rs | 12 +++++++++++ dpx/src/dpx_pdfparse.rs | 48 +++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/dpx/src/dpx_dpxutil.rs b/dpx/src/dpx_dpxutil.rs index 32be47b596..e8fb63ecd6 100644 --- a/dpx/src/dpx_dpxutil.rs +++ b/dpx/src/dpx_dpxutil.rs @@ -74,6 +74,18 @@ pub fn xtoi(c: u8) -> i32 { -1 } +pub fn xtoi_err(c: u8) -> Result { + if c.is_ascii_digit() { + Ok(c - b'0') + } else if (b'A'..=b'F').contains(&c) { + Ok(c - b'A' + 10) + } else if (b'a'..=b'f').contains(&c) { + Ok(c - b'a' + 10) + } else { + Err(()) + } +} + pub unsafe fn skip_white_spaces(s: *mut *mut u8, endptr: *mut u8) { while *s < endptr { if !(**s as i32 == ' ' as i32 diff --git a/dpx/src/dpx_pdfparse.rs b/dpx/src/dpx_pdfparse.rs index 12ad88cf13..1513d257a1 100644 --- a/dpx/src/dpx_pdfparse.rs +++ b/dpx/src/dpx_pdfparse.rs @@ -31,7 +31,7 @@ use crate::{info, warn}; use std::ffi::CString; use std::ptr; -use super::dpx_dpxutil::xtoi; +use super::dpx_dpxutil::{xtoi, xtoi_err}; use super::dpx_mem::new; use crate::dpx_pdfobj::{ pdf_deref_obj, pdf_dict, pdf_file, pdf_indirect, pdf_name, pdf_new_null, pdf_obj, @@ -829,26 +829,19 @@ impl ParsePdfObj for &[u8] { None } fn parse_pdf_name(&mut self) -> Option<*mut pdf_obj> { - unsafe fn pn_getc(pp: &mut &[u8]) -> i32 { - let mut ch; + fn pn_getc(pp: &mut &[u8]) -> Result { let p = *pp; if p[0] == b'#' { if p.len() <= 2 { *pp = &[]; - return -1; + return Err(()); } - if !p[1].is_ascii_hexdigit() || !p[2].is_ascii_hexdigit() { - *pp = &(*pp)[3..]; - return -1; - } - ch = xtoi(p[1]) << 4; - ch += xtoi(p[2]); *pp = &(*pp)[3..]; + Ok((xtoi_err(p[1])? << 4) + xtoi_err(p[2])?) } else { - ch = p[0] as i8 as i32; // TODO: more tests *pp = &(*pp)[1..]; + Ok(p[0]) } - ch } let mut name = Vec::::with_capacity(PDF_NAME_LEN_MAX); let mut len = 0; @@ -859,22 +852,25 @@ impl ParsePdfObj for &[u8] { } *self = &(*self)[1..]; while !self.is_empty() && !istokensep(&self[0]) { - let ch = unsafe { pn_getc(self) }; - if ch < 0 || ch > 0xff { - warn!("Invalid char in PDF name object. (ignored)"); - } else if ch == 0 { - warn!("Null char not allowed in PDF name object. (ignored)"); - } else if len < STRING_BUFFER_SIZE { - if len == PDF_NAME_LEN_MAX { - warn!("PDF name length too long. (>= {} bytes)", PDF_NAME_LEN_MAX); + if let Ok(ch) = pn_getc(self) { + if ch > 0x7f { + warn!("Invalid char in PDF name object. (ignored)"); + } else if ch == 0 { + warn!("Null char not allowed in PDF name object. (ignored)"); + } else if len < STRING_BUFFER_SIZE { + if len == PDF_NAME_LEN_MAX { + warn!("PDF name length too long. (>= {} bytes)", PDF_NAME_LEN_MAX); + } + name.push(ch as u8); + len += 1; + } else { + warn!( + "PDF name length too long. (>= {} bytes, truncated)", + STRING_BUFFER_SIZE + ); } - name.push(ch as u8); - len += 1; } else { - warn!( - "PDF name length too long. (>= {} bytes, truncated)", - STRING_BUFFER_SIZE - ); + warn!("Invalid char in PDF name object. (ignored)"); } } if len < 1 {