diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-03-20 15:17:08 +0000 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2022-03-21 16:31:06 +0000 |
commit | 5da13fe8c2fe685f3878d64df5bd55ad2a1b59c2 (patch) | |
tree | 127d08eaf764dba0bf0f99bf0570973d6b3c6f5c | |
parent | 0d39ef95e477ff984049545d300426d566520e7c (diff) | |
download | ghostpdl-5da13fe8c2fe685f3878d64df5bd55ad2a1b59c2.tar.gz |
OSS-fuzz #45842 - avoid recursion to prevent C-stack overflow
pdfi_read_token() was calling itself recursively under a few conditions;
a closing procedure character '}', on encountering a comment, or if we
found a token delimiter unexpectedly and were not stopping on errors.
The OSS-fuzz file has a large number of string closing characters ')',
which is a delimiter and the recursion eventually overflowed. Recursion
is overly clever for this, we don't need recursion we can simply
consume the character(s) and loop back to the start of the function to
get the next token.
-rw-r--r-- | pdf/pdf_int.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/pdf/pdf_int.c b/pdf/pdf_int.c index a23144d68..2eb6ffc6a 100644 --- a/pdf/pdf_int.c +++ b/pdf/pdf_int.c @@ -911,6 +911,7 @@ int pdfi_read_token(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, ui { int c, code; +rescan: pdfi_skip_white(ctx, s); c = pdfi_read_byte(ctx, s); @@ -1019,17 +1020,17 @@ int pdfi_read_token(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, ui break; case '}': pdfi_clear_to_mark(ctx); - return pdfi_read_token(ctx, s, indirect_num, indirect_gen); + goto rescan; break; case '%': pdfi_skip_comment(ctx, s); - return pdfi_read_token(ctx, s, indirect_num, indirect_gen); + goto rescan; break; default: if (isdelimiter(c)) { if (ctx->args.pdfstoponerror) return_error(gs_error_syntaxerror); - return pdfi_read_token(ctx, s, indirect_num, indirect_gen); + goto rescan; } pdfi_unread_byte(ctx, s, (byte)c); code = pdfi_read_keyword(ctx, s, indirect_num, indirect_gen); |