Based on e0c4b02429116b15ad1568c2c425f06b95b95830 Mon Sep 17 00:00:00 2001 From: Thomas Loimer Date: Sat, 25 Aug 2018 20:46:45 +0200 Subject: [PATCH] Harden input in read.c, fixes tickets #27 and #28 Also fixes issues similar to those described in https://sourceforge.net/p/mcj/tickets/27 and https://sourceforge.net/p/mcj/tickets/28. --- fig2dev/dev/readpcx.c | 2 - fig2dev/read.c | 48 +++++++++++++++++++++++++++++++++------------- fig2dev/tests/Makefile.am | 3 ++ fig2dev/tests/read.at | 44 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 15 deletions(-) --- fig2dev/read.c +++ fig2dev/read.c 2018-08-30 09:47:35.317361612 +0000 @@ -188,12 +188,24 @@ read_objects(FILE *fp, F_compound *obj) int object, coord_sys, len; memset((char*)obj, '\0', COMOBJ_SIZE); + (void) fgets(buf, BUFSIZ, fp); /* get the version line */ + if (strncmp(buf, "#FIG ", 5)) { + put_msg("Incorrect format string in first line of input file."); + return -1; + } + + /* remove newline and any carriage return (from a PC, perhaps) */ len = strlen(buf); - if (len > 0) - buf[len-1] = '\0'; /* remove newline */ - if (len > 1 && buf[len-2] == '\r') - buf[len-2] = '\0'; /* and any CR (from a PC perhaps) */ + if (buf[len-1] == '\n') { + if (buf[len-2] == '\r') + buf[len-2] = '\0'; + else + buf[len-1] = '\0'; + } else { /* fgets() only stops at newline and end-of-file */ + put_msg("File is truncated at first line."); + return -1; + } /* v2_flag is for version 2 or higher */ v2_flag = (!strncmp(buf, "#FIG 2", 6) || !strncmp(buf, "#FIG 3", 6)); @@ -886,6 +898,8 @@ read_lineobject(FILE *fp) l->next = NULL; l->join_style = 0; l->cap_style = 0; /* butt line cap */ + l->pic = NULL; + l->comments = NULL; sscanf(buf,"%*d%d",&l->type); /* get the line type */ @@ -968,12 +982,18 @@ read_lineobject(FILE *fp) char file[BUFSIZ], *c; size_t len; - Pic_malloc(l->pic); - l->pic->transp = -1; - if (l->pic == NULL) { + if ((Pic_malloc(l->pic)) == NULL) { free(l); return NULL; } + l->pic->transp = -1; + l->pic->bitmap = NULL; +#ifdef HAVE_X11_XPM_H + /* initialize l->pic->xpmimage by (ab)using a + public libxpm-function */ + XpmCreateXpmImageFromBuffer("", &l->pic->xpmimage, NULL); +#endif + /* %[^\n]: really, read until first '\0' in buf */ if (get_line(fp) < 0 || sscanf(buf, "%d %[^\n]", &l->pic->flipped, file) != 2) { @@ -1000,8 +1020,7 @@ read_lineobject(FILE *fp) l->pic->file = malloc(len = strlen(file) + 1); memcpy(l->pic->file, file, len); } - } else - l->pic = NULL; + } if (NULL == (l->points = Point_malloc(p))) { put_msg(Err_mem); @@ -1082,6 +1101,7 @@ read_splineobject(FILE *fp) s->fill_style = 0; s->for_arrow = NULL; s->back_arrow = NULL; + s->comments = NULL; s->next = NULL; if (v30_flag) { @@ -1270,6 +1290,7 @@ read_textobject(FILE *fp) Text_malloc(t); t->font = 0; t->size = 0.0; + t->comments = NULL; t->next = NULL; if (v30_flag) { /* order of parms is more like other objects now, @@ -1464,11 +1485,12 @@ get_line(FILE *fp) if (*buf == '#') { /* save any comments */ if (save_comment() < 0) return -1; - } else if (*buf != '\n') { /* Skip empty lines */ + /* skip empty lines */ + } else if (*buf != '\n' || !(*buf == '\r' && buf[1] == '\n')) { len = strlen(buf); - buf[len-1] = '\0'; /* strip trailing newline */ - if (buf[len-2] == '\r') - buf[len-2] = '\0'; /* strip trailing CRs */ + /* remove newline and possibly a carriage return */ + if (buf[len-1] == '\n') + buf[len - (buf[len-2] == '\r' ? 2 : 1)] = '\0'; return 1; } } --- fig2dev/dev/readpcx.c +++ fig2dev/dev/readpcx.c 2018-08-30 09:47:35.305361829 +0000 @@ -96,8 +96,6 @@ _read_pcx(FILE *pcxfile, F_pic *pic) fprintf(tfp, "%% Begin Imported PCX File: %s\n\n", pic->file); pic->subtype = P_PCX; - pic->bitmap=NULL; - fread(&header,1,sizeof(struct pcxhed),pcxfile); if (header.manuf!=10 || header.encod!=1) return 0; --- fig2dev/tests/Makefile.am +++ fig2dev/tests/Makefile.am 2018-08-30 09:47:35.321361539 +0000 @@ -40,6 +40,9 @@ $(srcdir)/package.m4: $(top_srcdir)/conf } >'$(srcdir)/package.m4' check_PROGRAMS = test1 +# test1 calls malloc(), may be replaced by a rpl_malloc() defined in malloc.o in +# LIBOBJS by AC_FUNC_MALLOC in configure.ac +test1_LDADD = $(LIBOBJS) # keep the definition below in sync with that in ../Makefile.am AM_CPPFLAGS = -DRGB_FILE="\"$(pkgdatadir)/rgb.txt\"" --- fig2dev/tests/read.at +++ fig2dev/tests/read.at 2018-08-30 09:47:35.325361467 +0000 @@ -208,6 +208,50 @@ EOF ],1,ignore,ignore) AT_CLEANUP +AT_SETUP([correctly free invalid spline, ticket #27]) +AT_KEYWORDS([read.c]) +AT_CHECK([fig2dev -L box <