summaryrefslogtreecommitdiff
path: root/pdf/pdf_int.c
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-03-20 15:17:08 +0000
committerKen Sharp <ken.sharp@artifex.com>2022-03-21 08:09:07 +0000
commit351ac4c05da840d52fb703e5f0a2f582989ef8a0 (patch)
tree593251d598c0ced226ad68e9875b341ee2c1cb2d /pdf/pdf_int.c
parent27df3bbca10141dbc458343d57c08621bf110738 (diff)
downloadghostpdl-351ac4c05da840d52fb703e5f0a2f582989ef8a0.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.
Diffstat (limited to 'pdf/pdf_int.c')
-rw-r--r--pdf/pdf_int.c7
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);