From 8e7bcd6952535163a919e1f6891b44521ba86a8d Mon Sep 17 00:00:00 2001 From: Ondrej Dubaj Date: Fri, 3 Sep 2021 08:15:34 +0200 Subject: [PATCH] Reject ASCII NUL anywhere in the input The input is read in line by line, stored in a buffer and processed further with sscanf(). Embedded NUL characters ('\0') would already disturb sscanf(), and nowhere does the code expect NUL characters. Therefore, detect NUL while reading the input, and exit with an error message when NUL is found anywere. Fixes ticket #80. --- CHANGES | 4 ++++ fig2dev/read.c | 21 +++++++++++++++++++-- fig2dev/tests/data/text_w_ascii0.fig | 12 ++++++++++++ fig2dev/tests/read.at | 16 ++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 fig2dev/tests/data/text_w_ascii0.fig diff --git a/CHANGES b/CHANGES index 4a414fa..f1bbbc3 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,10 @@ Patchlevel Xx (Xxx 20xx) BUGS FIXED: Ticket numbers refer to https://sourceforge.net/p/mcj/tickets/#. + o Fix ticket #81. + o Do not allow ASCII NUL anywhere in input. Fixes ticket #80. + o Use getline() to improve input scanning. + Fixes tickets #58, #59, #61, #62, #67, #78, #79. o Correctly scan embedded pdfs for /MediaBox value. o Convert polygons having too few points to polylines. Ticket #56. o Reject huge arrow types causing integer overflow. Ticket #57. diff --git a/fig2dev/read.c b/fig2dev/read.c index aea9537..6e47f2d 100644 --- a/fig2dev/read.c +++ b/fig2dev/read.c @@ -200,8 +200,14 @@ read_objects(FILE *fp, F_compound *obj) put_msg("Could not read input file."); return -1; } - /* seek to the end of the first line */ - if (strchr(buf, '\n') == NULL) { + + /* check for embedded '\0' */ + if (strlen(buf) < sizeof buf - 1 && buf[strlen(buf) - 1] != '\n') { + put_msg("ASCII NUL ('\\0') character within the first line."); + exit(EXIT_FAILURE); + /* seek to the end of the first line + (the only place, where '\0's are tolerated) */ + } else if (buf[strlen(buf) - 1] != '\n') { int c; do c = fgetc(fp); @@ -1399,6 +1405,15 @@ read_splineobject(FILE *fp, char **restrict line, size_t *line_len, return s; } +static void +exit_on_ascii_NUL(const char *restrict line, size_t chars, int line_no) +{ + if (strlen(line) < (size_t)chars) { + put_msg("ASCII NUL ('\\0') in line %d.", line_no); + exit(EXIT_FAILURE); + } +} + static char * find_end(const char *str, int v30flag) { @@ -1470,6 +1485,7 @@ read_textobject(FILE *fp, char **restrict line, size_t *line_len, int *line_no) while ((chars = getline(line, line_len, fp)) != -1) { ++(*line_no); + exit_on_ascii_NUL(*line, chars, *line_no); end = find_end(*line, v30_flag); if (end) { *end = '\0'; @@ -1641,6 +1657,7 @@ get_line(FILE *fp, char **restrict line, size_t *line_len, int *line_no) if (**line == '\n' || (**line == '\r' && chars == 2 && (*line)[1] == '\n')) continue; + exit_on_ascii_NUL(*line, chars, *line_no); /* remove newline and possibly a carriage return */ if ((*line)[chars-1] == '\n') { chars -= (*line)[chars - 2] == '\r' ? 2 : 1; diff --git a/fig2dev/tests/data/text_w_ascii0.fig b/fig2dev/tests/data/text_w_ascii0.fig new file mode 100644 index 0000000..c0aa754 --- /dev/null +++ b/fig2dev/tests/data/text_w_ascii0.fig @@ -0,0 +1,12 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +4 0 0 2 0 25 163 31 7 0 0 -1 1 0 2 + 0& 4 120 5 y\ 0 0 0^^^^^J^^^^^ÿÿ^^^^^^^^^^^^^^^^^^^^^^45 E\0I1y\001 +#4 0 0 50 -1 -1 12 0.0 0 150 405 0 0 An ascii zero '\\0' here ->...and some more text following, with a certain amount of minimum characters\001 diff --git a/fig2dev/tests/read.at b/fig2dev/tests/read.at index 9b34bfb..60982b0 100644 --- a/fig2dev/tests/read.at +++ b/fig2dev/tests/read.at @@ -406,6 +406,22 @@ EOF ]) AT_CLEANUP +AT_SETUP([allow tex font -1, ticket #81]) +AT_KEYWORDS([pict2e tikz]) +AT_DATA([text.fig], [FIG_FILE_TOP +4 0 0 50 -1 -1 12 0.0 0 150 405 0 0 Text\001 +]) +AT_CHECK([fig2dev -L pict2e text.fig +], 0, ignore) +AT_CHECK([fig2dev -L tikz text.fig +], 0, ignore) +AT_CLEANUP + +AT_SETUP([reject ASCII NUL ('\0') in input, ticket #80]) +AT_KEYWORDS([read.c svg]) +AT_CHECK([fig2dev -L svg $srcdir/data/text_w_ascii0.fig], 1, ignore, ignore) +AT_CLEANUP + AT_BANNER([Dynamically allocate picture file name.]) AT_SETUP([prepend fig file path to picture file name]) -- 2.31.1