Hi Karl, hi all, On Sa, 07 Sep 2013, Karl Berry wrote: > #define TAIL(x) (x+strlen(x))
Done, fixed patch attached: mendex-bugfix > In general, shouldn't snprintf be used to avoid the whole potential of > buffer overrun? Done that for fwrite.c, but there are other cases in the source. Patch for fwrite.c attached, on top of the prvious: mendex-snprintf If anyone can comment on that (review) that would be great, especially the definition of TAIL_LEN(x) (returning two argumetns, the pointer and the remaining length, for the first two arguments of snprintf). Thanks Norbert ------------------------------------------------------------------------ PREINING, Norbert http://www.preining.info JAIST, Japan TeX Live & Debian Developer DSA: 0x09C5B094 fp: 14DF 2E6C 0307 BE6D AD76 A9C0 D2BF 4AA3 09C5 B094 ------------------------------------------------------------------------
fix a bug in mendex when range ops and macros are used (Closes: #534641) --- texk/mendexk/ChangeLog | 9 +++++++++ texk/mendexk/fwrite.c | 5 ++--- 2 files changed, 11 insertions(+), 3 deletions(-) --- texlive-bin.orig/texk/mendexk/ChangeLog +++ texlive-bin/texk/mendexk/ChangeLog @@ -1,3 +1,12 @@ +2013-09-08 Norbert Preining <prein...@logic.at> + + * fwrite.c: properly parenthesis TAIL macro + +2013-09-07 Norbert Preining <prein...@logic.at> + + * fwrite.c: fix missing output when range operators are + used with macro definitions + 2012-11-19 Peter Breitenlohner <p...@mppmu.mpg.de> * Makefile.am: Avoid use of deprecated INCLUDES. --- texlive-bin.orig/texk/mendexk/fwrite.c +++ texlive-bin/texk/mendexk/fwrite.c @@ -15,7 +15,7 @@ static void linecheck(char *lbuff, char *tmpbuff); static void crcheck(char *lbuff, FILE *fp); -#define TAIL(x) (x+strlen(x)) +#define TAIL(x) ((x)+strlen(x)) /* if we don't have vsnprintf() */ /* #define vsnprintf(buff,len,format,argptr) vsprintf(buff,format,argptr) */ @@ -384,8 +384,7 @@ ind.p[j].enc++; } if (strlen(ind.p[j].enc)>0) { - sprintf(tmpbuff,"%s%s%s",encap_prefix,ind.p[j].enc,encap_infix); - sprintf(tmpbuff,"%s%s%s",ind.p[j].page,encap_suffix,delim_n); + sprintf(tmpbuff,"%s%s%s%s%s%s",encap_prefix,ind.p[j].enc,encap_infix,ind.p[j].page,encap_suffix,delim_n); linecheck(lbuff,tmpbuff); } }
--- texk/mendexk/ChangeLog | 1 texk/mendexk/fwrite.c | 103 +++++++++++++++++++++++++------------------------ 2 files changed, 54 insertions(+), 50 deletions(-) --- texlive-bin.orig/texk/mendexk/ChangeLog +++ texlive-bin/texk/mendexk/ChangeLog @@ -1,6 +1,7 @@ 2013-09-08 Norbert Preining <prein...@logic.at> * fwrite.c: properly parenthesis TAIL macro + * fwrite.c: replace sprintf with snprintf 2013-09-07 Norbert Preining <prein...@logic.at> --- texlive-bin.orig/texk/mendexk/fwrite.c +++ texlive-bin/texk/mendexk/fwrite.c @@ -10,12 +10,15 @@ int line_length=0; +#define BUFFERLEN 4096 + static void printpage(struct index *ind, FILE *fp, int num, char *lbuff); static int range_check(struct index ind, int count, char *lbuff); static void linecheck(char *lbuff, char *tmpbuff); static void crcheck(char *lbuff, FILE *fp); #define TAIL(x) ((x)+strlen(x)) +#define TAIL_LEN(x) ((x)+strlen(x)), (BUFFERLEN-strlen(x)) /* if we don't have vsnprintf() */ /* #define vsnprintf(buff,len,format,argptr) vsprintf(buff,format,argptr) */ @@ -67,7 +70,7 @@ void indwrite(char *filename, struct index *ind, int pagenum) { int i,j,hpoint=0; - char datama[256],lbuff[4096]; + char datama[256],lbuff[BUFFERLEN]; FILE *fp; if (filename[0]!='\0' && kpse_out_name_ok(filename)) fp=fopen(filename,"wb"); @@ -99,7 +102,7 @@ fprintf(fp,"%s%s%s",lethead_prefix,symhead_negative,lethead_suffix); } } - sprintf(lbuff,"%s%s",item_0,ind[i].idx[0]); + snprintf(lbuff, BUFFERLEN, "%s%s",item_0,ind[i].idx[0]); } else if (alphabet(ind[i].dic[0][0])) { if (lethead_flag>0) { @@ -108,7 +111,7 @@ else if (lethead_flag<0) { fprintf(fp,"%s%c%s",lethead_prefix,ind[i].dic[0][0]+32,lethead_suffix); } - sprintf(lbuff,"%s%s",item_0,ind[i].idx[0]); + snprintf(lbuff, BUFFERLEN, "%s%s",item_0,ind[i].idx[0]); } else if (japanese(ind[i].dic[0])) { if (lethead_flag) { @@ -125,7 +128,7 @@ } fputs(lethead_suffix,fp); } - sprintf(lbuff,"%s%s",item_0,ind[i].idx[0]); + snprintf(lbuff, BUFFERLEN, "%s%s",item_0,ind[i].idx[0]); for (hpoint=0;hpoint<(strlen(datama)/2);hpoint++) { if ((unsigned char)ind[i].dic[0][1]<(unsigned char)datama[hpoint*2+1]) { break; @@ -134,18 +137,18 @@ } switch (ind[i].words) { case 1: - sprintf(TAIL(lbuff),"%s",delim_0); + snprintf(TAIL_LEN(lbuff), "%s",delim_0); break; case 2: - sprintf(TAIL(lbuff),"%s%s",item_x1,ind[i].idx[1]); - sprintf(TAIL(lbuff),"%s",delim_1); + snprintf(TAIL_LEN(lbuff), "%s%s",item_x1,ind[i].idx[1]); + snprintf(TAIL_LEN(lbuff), "%s",delim_1); break; case 3: - sprintf(TAIL(lbuff),"%s%s",item_x1,ind[i].idx[1]); - sprintf(TAIL(lbuff),"%s%s",item_x2,ind[i].idx[2]); - sprintf(TAIL(lbuff),"%s",delim_2); + snprintf(TAIL_LEN(lbuff),"%s%s",item_x1,ind[i].idx[1]); + snprintf(TAIL_LEN(lbuff),"%s%s",item_x2,ind[i].idx[2]); + snprintf(TAIL_LEN(lbuff),"%s",delim_2); break; default: @@ -201,41 +204,41 @@ switch (ind[i].words) { case 1: - sprintf(TAIL(lbuff),"%s%s%s",item_0,ind[i].idx[0],delim_0); + snprintf(TAIL_LEN(lbuff),"%s%s%s",item_0,ind[i].idx[0],delim_0); break; case 2: if (strcmp(ind[i-1].idx[0],ind[i].idx[0])!=0 || strcmp(ind[i-1].dic[0],ind[i].dic[0])!=0) { - sprintf(TAIL(lbuff),"%s%s%s",item_0,ind[i].idx[0],item_x1); + snprintf(TAIL_LEN(lbuff),"%s%s%s",item_0,ind[i].idx[0],item_x1); } else { if (ind[i-1].words==1) { - sprintf(TAIL(lbuff),"%s",item_01); + snprintf(TAIL_LEN(lbuff),"%s",item_01); } else { - sprintf(TAIL(lbuff),"%s",item_1); + snprintf(TAIL_LEN(lbuff),"%s",item_1); } } - sprintf(TAIL(lbuff),"%s",ind[i].idx[1]); - sprintf(TAIL(lbuff),"%s",delim_1); + snprintf(TAIL_LEN(lbuff),"%s",ind[i].idx[1]); + snprintf(TAIL_LEN(lbuff),"%s",delim_1); break; case 3: if (strcmp(ind[i-1].idx[0],ind[i].idx[0])!=0 || strcmp(ind[i-1].dic[0],ind[i].dic[0])!=0) { - sprintf(TAIL(lbuff),"%s%s",item_0,ind[i].idx[0]); - sprintf(TAIL(lbuff),"%s%s%s",item_x1,ind[i].idx[1],item_x2); + snprintf(TAIL_LEN(lbuff),"%s%s",item_0,ind[i].idx[0]); + snprintf(TAIL_LEN(lbuff),"%s%s%s",item_x1,ind[i].idx[1],item_x2); } else if (ind[i-1].words==1) { - sprintf(TAIL(lbuff),"%s%s%s",item_01,ind[i].idx[1],item_x2); + snprintf(TAIL_LEN(lbuff),"%s%s%s",item_01,ind[i].idx[1],item_x2); } else if (strcmp(ind[i-1].idx[1],ind[i].idx[1])!=0 || strcmp(ind[i-1].dic[1],ind[i].dic[1])!=0) { - if (ind[i-1].words==2) sprintf(TAIL(lbuff),"%s%s%s",item_1,ind[i].idx[1],item_12); - else sprintf(TAIL(lbuff),"%s%s%s",item_1,ind[i].idx[1],item_x2); + if (ind[i-1].words==2) snprintf(TAIL_LEN(lbuff),"%s%s%s",item_1,ind[i].idx[1],item_12); + else snprintf(TAIL_LEN(lbuff),"%s%s%s",item_1,ind[i].idx[1],item_x2); } else { - sprintf(TAIL(lbuff),"%s",item_2); + snprintf(TAIL_LEN(lbuff),"%s",item_2); } - sprintf(TAIL(lbuff),"%s%s",ind[i].idx[2],delim_2); + snprintf(TAIL_LEN(lbuff),"%s%s",ind[i].idx[2],delim_2); break; default: @@ -253,7 +256,7 @@ static void printpage(struct index *ind, FILE *fp, int num, char *lbuff) { int i,j,k,cc; - char buff[4096],tmpbuff[4096],errbuff[4096]; + char buff[BUFFERLEN],tmpbuff[BUFFERLEN],errbuff[BUFFERLEN]; buff[0]=tmpbuff[0]='\0'; @@ -272,25 +275,25 @@ || ind[num].p[j].enc[0]==range_close) ind[num].p[j].enc++; if (strlen(ind[num].p[j].enc)>0) { - sprintf(buff,"%s%s%s",encap_prefix,ind[num].p[j].enc,encap_infix); + snprintf(buff,"%s%s%s",encap_prefix,ind[num].p[j].enc,encap_infix); } if (strlen(suffix_3p)>0 && (pnumconv(ind[num].p[cc].page,ind[num].p[cc].attr[0])-pnumconv(ind[num].p[j].page,ind[num].p[j].attr[0]))==2) { - sprintf(TAIL(buff),"%s%s",ind[num].p[j].page,suffix_3p); + snprintf(TAIL_LEN(buff),"%s%s",ind[num].p[j].page,suffix_3p); } else if (strlen(suffix_mp)>0 && (pnumconv(ind[num].p[cc].page,ind[num].p[cc].attr[0])-pnumconv(ind[num].p[j].page,ind[num].p[j].attr[0]))>=2) { - sprintf(TAIL(buff),"%s%s",ind[num].p[j].page,suffix_mp); + snprintf(TAIL_LEN(buff),"%s%s",ind[num].p[j].page,suffix_mp); } else if (strlen(suffix_2p)>0 && (pnumconv(ind[num].p[cc].page,ind[num].p[cc].attr[0])-pnumconv(ind[num].p[j].page,ind[num].p[j].attr[0]))==1) { - sprintf(TAIL(buff),"%s%s",ind[num].p[j].page,suffix_2p); + snprintf(TAIL_LEN(buff),"%s%s",ind[num].p[j].page,suffix_2p); } else { - sprintf(TAIL(buff),"%s%s",ind[num].p[j].page,delim_r); - sprintf(TAIL(buff),"%s",ind[num].p[cc].page); + snprintf(TAIL_LEN(buff),"%s%s",ind[num].p[j].page,delim_r); + snprintf(TAIL_LEN(buff),"%s",ind[num].p[cc].page); } - sprintf(TAIL(tmpbuff),"%s",buff); + snprintf(TAIL_LEN(tmpbuff),"%s",buff); buff[0]='\0'; if (strlen(ind[num].p[j].enc)>0) { - sprintf(TAIL(tmpbuff),"%s",encap_suffix); + snprintf(TAIL_LEN(tmpbuff),"%s",encap_suffix); } linecheck(lbuff,tmpbuff); j=cc; @@ -298,53 +301,53 @@ goto PRINT; } else { - sprintf(TAIL(tmpbuff),"%s",delim_n); + snprintf(TAIL_LEN(tmpbuff),"%s",delim_n); linecheck(lbuff,tmpbuff); } } else if (strlen(ind[num].p[j].enc)>0) { /* normal encap */ if (ind[num].p[j].enc[0]==range_close) { - sprintf(errbuff,"Warning: Unmatched range closing operator \'%c\',",range_close); - for (i=0;i<ind[num].words;i++) sprintf(TAIL(errbuff),"%s.",ind[num].idx[i]); + sprintf(errbuff, "Warning: Unmatched range closing operator \'%c\',",range_close); + for (i=0;i<ind[num].words;i++) snprintf(TAIL_LEN(errbuff),"%s.",ind[num].idx[i]); warn_printf(efp, "%s\n", errbuff); ind[num].p[j].enc++; } if (strlen(ind[num].p[j].enc)>0) { - sprintf(TAIL(tmpbuff),"%s%s%s",encap_prefix,ind[num].p[j].enc,encap_infix); - sprintf(TAIL(tmpbuff),"%s%s%s",ind[num].p[j].page,encap_suffix,delim_n); + snprintf(TAIL_LEN(tmpbuff),"%s%s%s",encap_prefix,ind[num].p[j].enc,encap_infix); + snprintf(TAIL_LEN(tmpbuff),"%s%s%s",ind[num].p[j].page,encap_suffix,delim_n); linecheck(lbuff,tmpbuff); } else { - sprintf(TAIL(tmpbuff),"%s%s",ind[num].p[j].page,delim_n); + snprintf(TAIL_LEN(tmpbuff),"%s%s",ind[num].p[j].page,delim_n); linecheck(lbuff,tmpbuff); } } else { /* no encap */ - sprintf(TAIL(tmpbuff),"%s%s",ind[num].p[j].page,delim_n); + snprintf(TAIL_LEN(tmpbuff),"%s%s",ind[num].p[j].page,delim_n); linecheck(lbuff,tmpbuff); } } if (ind[num].p[j].enc[0]==range_open) { sprintf(errbuff,"Warning: Unmatched range opening operator \'%c\',",range_open); - for (k=0;k<ind[num].words;k++) sprintf(TAIL(errbuff),"%s.",ind[num].idx[k]); + for (k=0;k<ind[num].words;k++) snprintf(TAIL_LEN(errbuff),"%s.",ind[num].idx[k]); warn_printf(efp, "%s\n", errbuff); ind[num].p[j].enc++; } else if (ind[num].p[j].enc[0]==range_close) { sprintf(errbuff,"Warning: Unmatched range closing operator \'%c\',",range_close); - for (k=0;k<ind[num].words;k++) sprintf(TAIL(errbuff),"%s.",ind[num].idx[k]); + for (k=0;k<ind[num].words;k++) snprintf(TAIL_LEN(errbuff),"%s.",ind[num].idx[k]); warn_printf(efp, "%s\n", errbuff); ind[num].p[j].enc++; } if (strlen(ind[num].p[j].enc)>0) { - sprintf(TAIL(tmpbuff),"%s%s%s",encap_prefix,ind[num].p[j].enc,encap_infix); - sprintf(TAIL(tmpbuff),"%s%s",ind[num].p[j].page,encap_suffix); + snprintf(TAIL_LEN(tmpbuff),"%s%s%s",encap_prefix,ind[num].p[j].enc,encap_infix); + snprintf(TAIL_LEN(tmpbuff),"%s%s",ind[num].p[j].page,encap_suffix); } else { - sprintf(TAIL(tmpbuff),"%s",ind[num].p[j].page); + snprintf(TAIL_LEN(tmpbuff),"%s",ind[num].p[j].page); } linecheck(lbuff,tmpbuff); @@ -362,7 +365,7 @@ for (i=count;i<ind.num+1;i++) { if (ind.p[i].enc[0]==range_close) { sprintf(errbuff,"Warning: Unmatched range closing operator \'%c\',",range_close); - sprintf(TAIL(errbuff),"%s.",ind.idx[0]); + snprintf(TAIL_LEN(errbuff),"%s.",ind.idx[0]); warn_printf(efp, "%s\n", errbuff); ind.p[i].enc++; } @@ -379,19 +382,19 @@ } else if (j!=i && ind.p[j].enc[0]==range_open) { sprintf(errbuff,"Warning: Unmatched range opening operator \'%c\',",range_open); - for (k=0;k<ind.words;k++) sprintf(TAIL(errbuff),"%s.",ind.idx[k]); + for (k=0;k<ind.words;k++) snprintf(TAIL_LEN(errbuff),"%s.",ind.idx[k]); warn_printf(efp, "%s\n", errbuff); ind.p[j].enc++; } if (strlen(ind.p[j].enc)>0) { - sprintf(tmpbuff,"%s%s%s%s%s%s",encap_prefix,ind.p[j].enc,encap_infix,ind.p[j].page,encap_suffix,delim_n); + snprintf(tmpbuff, BUFFERLEN, "%s%s%s%s%s%s",encap_prefix,ind.p[j].enc,encap_infix,ind.p[j].page,encap_suffix,delim_n); linecheck(lbuff,tmpbuff); } } } if (j==ind.num+1) { sprintf(errbuff,"Warning: Unmatched range opening operator \'%c\',",range_open); - for (k=0;k<ind.words;k++) sprintf(TAIL(errbuff),"%s.",ind.idx[k]); + for (k=0;k<ind.words;k++) snprintf(TAIL_LEN(errbuff),"%s.",ind.idx[k]); warn_printf(efp, "%s\n", errbuff); } i=j-1; @@ -423,12 +426,12 @@ static void linecheck(char *lbuff, char *tmpbuff) { if (line_length+strlen(tmpbuff)>line_max) { - sprintf(TAIL(lbuff),"\n%s%s",indent_space,tmpbuff); + snprintf(TAIL_LEN(lbuff),"\n%s%s",indent_space,tmpbuff); line_length=indent_length+strlen(tmpbuff); tmpbuff[0]='\0'; } else { - sprintf(TAIL(lbuff),"%s",tmpbuff); + snprintf(TAIL_LEN(lbuff),"%s",tmpbuff); line_length+=strlen(tmpbuff); tmpbuff[0]='\0'; }