diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-06-21 19:21:31 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-06-21 19:21:31 +0100 |
commit | d23dae61660efa3b88553988935348e4a8cd2143 (patch) | |
tree | 9c7b822e643687958e512f960ce580d06fd654ef | |
parent | 57ef7adeab09993a203b74245ab1caeed76f98b1 (diff) | |
download | mupdf-d23dae61660efa3b88553988935348e4a8cd2143.tar.xz |
Add fz_buffer_cat_pdf_string function to avoid Bug 693143.
Avoid overflowing fz_buffer_printf by using a dedicated string
output function; this also solves potential problems with us not
escaping chars in strings correctly.
Unfortunately this doesn't completely cure the bug as we run
straight into problems in the lexer.
-rw-r--r-- | fitz/fitz-internal.h | 7 | ||||
-rw-r--r-- | fitz/stm_buffer.c | 76 | ||||
-rw-r--r-- | pdf/pdf_form.c | 5 |
3 files changed, 86 insertions, 2 deletions
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h index 95bb2eda..b7401718 100644 --- a/fitz/fitz-internal.h +++ b/fitz/fitz-internal.h @@ -436,6 +436,13 @@ void fz_write_buffer_pad(fz_context *ctx, fz_buffer *buf); */ void fz_buffer_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...); +/* + fz_buffer_printf: print a string formatted as a pdf string to a buffer. + The buffer will grow. +*/ +void +fz_buffer_cat_pdf_string(fz_context *ctx, fz_buffer *buffer, const char *text); + struct fz_stream_s { fz_context *ctx; diff --git a/fitz/stm_buffer.c b/fitz/stm_buffer.c index 7d1884af..1202617e 100644 --- a/fitz/stm_buffer.c +++ b/fitz/stm_buffer.c @@ -187,3 +187,79 @@ fz_buffer_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...) va_end(args); } + +void +fz_buffer_cat_pdf_string(fz_context *ctx, fz_buffer *buffer, const char *text) +{ + int len = 2; + const char *s = text; + char *d; + char c; + + while (c = *s++) + { + switch (c) + { + case '\n': + case '\r': + case '\t': + case '\b': + case '\f': + case '(': + case ')': + case '\\': + len++; + break; + } + len++; + } + + while(buffer->cap - buffer->len < len) + fz_grow_buffer(ctx, buffer); + + s = text; + d = (char *)buffer->data + buffer->len; + *d++ = '('; + while (c = *s++) + { + switch (c) + { + case '\n': + *d++ = '\\'; + *d++ = 'n'; + break; + case '\r': + *d++ = '\\'; + *d++ = 'r'; + break; + case '\t': + *d++ = '\\'; + *d++ = 't'; + break; + case '\b': + *d++ = '\\'; + *d++ = 'b'; + break; + case '\f': + *d++ = '\\'; + *d++ = 'f'; + break; + case '(': + *d++ = '\\'; + *d++ = '('; + break; + case ')': + *d++ = '\\'; + *d++ = ')'; + break; + case '\\': + *d++ = '\\'; + *d++ = '\\'; + break; + default: + *d++ = c; + } + } + *d++ = ')'; + buffer->len += len; +} diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c index 8d8f598e..45510aac 100644 --- a/pdf/pdf_form.c +++ b/pdf/pdf_form.c @@ -78,7 +78,7 @@ static const char *fmt_n = "n\n"; static const char *fmt_BT = "BT\n"; static const char *fmt_Tm = "%1.2f %1.2f %1.2f %1.2f %1.2f %1.2f Tm\n"; static const char *fmt_Td = "%f %f Td\n"; -static const char *fmt_Tj = "(%s) Tj\n"; +static const char *fmt_Tj = " Tj\n"; static const char *fmt_ET = "ET\n"; static const char *fmt_Q = "Q\n"; static const char *fmt_EMC = "EMC\n"; @@ -422,7 +422,8 @@ static void fzbuf_print_text(fz_context *ctx, fz_buffer *fzbuf, fz_rect *clip, f if (tm) fz_buffer_printf(ctx, fzbuf, fmt_Tm, tm->a, tm->b, tm->c, tm->d, tm->e, tm->f); - fz_buffer_printf(ctx, fzbuf, fmt_Tj, text); + fz_buffer_cat_pdf_string(ctx, fzbuf, text); + fz_buffer_printf(ctx, fzbuf, fmt_Tj); fz_buffer_printf(ctx, fzbuf, fmt_ET); fz_buffer_printf(ctx, fzbuf, fmt_Q); } |