summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2023-02-14 16:03:40 +0000
committerKen Sharp <ken.sharp@artifex.com>2023-02-14 16:03:40 +0000
commit03e485b0a99d4cd94011f3d217be77de25ac8c4c (patch)
treebe92945b6d1ac0bd8754df93b66d16744e95b300 /pdf
parent372b7efe8d597b56fb96bf6137af42a48e644fb4 (diff)
downloadghostpdl-03e485b0a99d4cd94011f3d217be77de25ac8c4c.tar.gz
GhostPDF - spot errors in hex strings in fonts/CMaps
This was inspired by OSS-fuzz bug #55443, the PDF file has a CMap which is corrupted, a hex string defining an entry in the CMap has some garbage inserted into it. This causes the CMap to have an extremely large range, which takes a very long time to work through. Short-circuiting this by detecting the error in the hex string makes the file complete much more quickly. Since the CMap is corrupted the result is always going to be incorrect anyway and at least this way we stop processing it more quickly. Because CMaps and fonts use the same parser, this then exhibited an error with a lot of fonts, particularly the PostScript emitted by ps2write. It turns out that the eexec encrypted portion of the font has rubbish following the 'currentfile closefile' and in some cases this included an opening hex string marker '<' followed by non-hex data. Obviously we shouldn't be processing that, I think we're lucky to have got away with it to date. To fix the problem, create an operator for fonts to deal with the 'closefile', and have that consume all the remaining data in the buffer.
Diffstat (limited to 'pdf')
-rw-r--r--pdf/pdf_fontps.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/pdf/pdf_fontps.c b/pdf/pdf_fontps.c
index f8e0fe82b..fea853d16 100644
--- a/pdf/pdf_fontps.c
+++ b/pdf/pdf_fontps.c
@@ -206,10 +206,16 @@ pdfi_pscript_interpret(pdf_ps_ctx_t *cs, byte *pdfpsbuf, int64_t buflen)
for (i = 0; i < len; i += 2) {
hbuf[0] = s[i];
hbuf[1] = s[i + 1];
+ if (!ishex(hbuf[0]) || !ishex(hbuf[1])) {
+ code = gs_note_error(gs_error_typecheck);
+ break;
+ }
*s2++ = (decodehex(hbuf[0]) << 4) | decodehex(hbuf[1]);
}
- pdfpsbuf++; /* move past the trailing '>' */
- code = pdf_ps_stack_push_string(cs, s, len >> 1);
+ if (i >= len) {
+ pdfpsbuf++; /* move past the trailing '>' */
+ code = pdf_ps_stack_push_string(cs, s, len >> 1);
+ }
}
break;
case '>': /* For hex strings, this should be handled above */
@@ -1212,6 +1218,12 @@ pdf_ps_put_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
return code;
}
+static int
+pdf_ps_closefile_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
+{
+ return bufend - buf;
+}
+
static pdf_ps_oper_list_t ps_font_oper_list[] = {
{PDF_PS_OPER_NAME_AND_LEN("RD"), pdf_ps_RD_oper_func},
{PDF_PS_OPER_NAME_AND_LEN("-|"), pdf_ps_RD_oper_func},
@@ -1236,6 +1248,7 @@ static pdf_ps_oper_list_t ps_font_oper_list[] = {
{PDF_PS_OPER_NAME_AND_LEN("for"), pdf_ps_pop4_oper_func},
{PDF_PS_OPER_NAME_AND_LEN("put"), pdf_ps_put_oper_func},
{PDF_PS_OPER_NAME_AND_LEN("StandardEncoding"), pdf_ps_standardencoding_oper_func},
+ {PDF_PS_OPER_NAME_AND_LEN("closefile"), pdf_ps_closefile_oper_func},
{NULL, 0, NULL}
};