Change:
<ins> --- a/externs.h +++ b/externs.h @@ -260,6 +260,9 @@ If you're compiling this, you've got the /*                      that can appear correctly on one page.  Can be       */ /*                      increased to any small positive integer.             */ /*                                                                           */ +/*  MAX_FORMAT          The maximum number of characters for sscanf formats  */ +/*                      for splitting strings with tab-delimited fields.     */ +/*                                                                           */ /*****************************************************************************/ #define	MAX_FULL_LENGTH	8388607	/* 2**23 - 1, about 148 metres */ @@ -275,6 +278,7 @@ If you're compiling this, you've got the #define	MAX_LEX_STACK	20 #define	MAX_CHARS	256 #define MAX_HCOPIES	3 +#define MAX_FORMAT	100 /*****************************************************************************/ /*                                                                           */ --- a/z02.c +++ b/z02.c @@ -378,7 +378,7 @@ static void srcnext(void) if( blksize != 0 && chpt < limit ) { debugcond0(DLA, DD, stack_free <= 1, "srcnext: transferring."); col = buf; -    while( chtbl[(*--col = *--limit)] != NEWLINE ); +    while( col > mem_block && chtbl[(*--col = *--limit)] != NEWLINE ); frst = col + 1;  limit++;  blksize = 0; } --- a/z33.c +++ b/z33.c @@ -847,6 +847,7 @@ BOOLEAN DbRetrieve(OBJECT db, BOOLEAN ga BOOLEAN DbRetrieveNext(OBJECT db, BOOLEAN *gall, OBJECT *sym, FULL_CHAR *tag, FULL_CHAR *seq, FILE_NUM *dfnum, long *dfpos, int *dlnum, long *cont) { FULL_CHAR line[MAX_BUFF], *cline, fname[MAX_BUFF]; int symnum; +  char format[MAX_FORMAT]; ifdebug(DPP, D, ProfileOn("DbRetrieveNext")); debug2(DBS, DD, "DbRetrieveNext( %s, %ld )", string(db), *cont); assert(reading(db), "DbRetrieveNext: not reading"); @@ -858,6 +859,8 @@ BOOLEAN DbRetrieveNext(OBJECT db, BOOLEA return FALSE; } +  sprintf(format, "%%d&%%%d[^t]t%%%d[^t]t%%*[^t]t%%ldt%%dt%%%d[^nf]", MAX_BUFF-1, MAX_BUFF-1, MAX_BUFF-1); + if( in_memory(db) ) { /* get next entry from internal database */ @@ -868,7 +871,7 @@ BOOLEAN DbRetrieveNext(OBJECT db, BOOLEA } cline = (FULL_CHAR *) db_lines(db)[*cont]; *gall = (cline[0] == '0' ? 1 : 0); -    sscanf((char *)&cline[*gall], "%d&%[^t]t%[^t]t%*[^t]t%ldt%dt%[^nf]", +    sscanf((char *)&cline[*gall], format, &symnum, tag, seq, dfpos, dlnum, fname); *cont = *cont + 1; } @@ -882,7 +885,7 @@ BOOLEAN DbRetrieveNext(OBJECT db, BOOLEA return FALSE; } *gall = (line[0] == '0' ? 1 : 0); -    sscanf((char *)&line[*gall], "%d&%[^t]t%[^t]t%*[^t]t%ldt%dt%[^nf]", +    sscanf((char *)&line[*gall], format, &symnum, tag, seq, dfpos, dlnum, fname); *cont = ftell(db_filep(db)); } --- a/z39.c +++ b/z39.c @@ -79,11 +79,13 @@ int strcollcmp(char *a, char *b) int strcollcmp(char *a, char *b) { char a1[MAX_BUFF], a2[MAX_BUFF], a3[MAX_BUFF]; char b1[MAX_BUFF], b2[MAX_BUFF], b3[MAX_BUFF]; +  char format[MAX_FORMAT]; int order; +  sprintf(format, "%%%d[^t]t%%%d[^t]t%%%d[^t]", MAX_BUFF-1, MAX_BUFF-1, MAX_BUFF-1); a1[0] = a2[0] = a3[0] = '0'; -  sscanf(a, "%[^t]t%[^t]t%[^t]", a1, a2, a3); +  sscanf(a, format, a1, a2, a3); b1[0] = b2[0] = b3[0] = '0'; -  sscanf(b, "%[^t]t%[^t]t%[^t]", b1, b2, b3); +  sscanf(b, format, b1, b2, b3); order = strcoll(a1, b1); if( order == 0 ) { @@ -251,7 +253,7 @@ FULL_CHAR *StringQuotedWord(OBJECT x) *q++ = CH_QUOTE; for( p = string(x);  *p != '0';  p++ ) { -    for( r = (FULL_CHAR *) quoted_string[*p];  *r != '0';  *q++ = *r++ ); +    for( r = (FULL_CHAR *) quoted_string[*p];  *r != '0' && q < &buff[MAX_BUFF-2];  *q++ = *r++ ); } *q++ = CH_QUOTE; *q++ = '0'; </ins>

Discussion:
, CVSSv3=7.8 (nixos-20.09, nixos-unstable) Scanned versions: nixos-20.09: ; nixos-unstable: .
See also:

, CVSSv3=7.8 (nixos-20.03, nixos-unstable) Scanned versions: nixos-20.03: ; nixos-unstable: . May contain false positives.