Merge branch 'master' into cc_func-avoid-undefined-behaviour

This commit is contained in:
Leonardo Taccari 2019-01-28 17:34:58 +01:00 committed by GitHub
commit 031aac816d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 265 additions and 53 deletions

View File

@ -1,3 +1,9 @@
2018-08-29 Arnold D. Robbins <arnold@skeeve.com>
* REGRESS: Check for existence of a.out. If not there, run
make. Enable core dumps for T.arnold system status test
to work on MacOS X.
2018-08-22 Arnold D. Robbins <arnold@skeeve.com>
* awktest.tar (testdir/T.expr): Fix test for unary plus.

5
FIXES
View File

@ -25,6 +25,11 @@ THIS SOFTWARE.
This file lists all bug fixes, changes, etc., made since the AWK book
was sent to the printers in August, 1987.
Oct 25, 2018:
Added test in maketab.c to prevent generating a proctab entry
for YYSTYPE_IS_DEFINED. It was harmless but some gcc settings
generated a warning message. Thanks to Nan Xiao for report.
Aug 27, 2018:
Disallow '$' in printf formats; arguments evaluated in order
and printed in order.

15
REGRESS
View File

@ -1,5 +1,15 @@
#! /bin/sh
case `uname` in
CYGWIN) EXE=a.exe ;;
*) EXE=a.out ;;
esac
if [ ! -f $EXE ]
then
make || exit 1
fi
if [ -d testdir ]
then
true # do nothing
@ -16,5 +26,10 @@ cd testdir
pwd
PATH=.:$PATH
export PATH
if (ulimit -c unlimited > /dev/null 2>&1)
then
# Workaround broken default on MacOS X
ulimit -c unlimited
fi
REGRESS

5
awk.h
View File

@ -97,9 +97,14 @@ extern Array *symtab;
extern Cell *nrloc; /* NR */
extern Cell *fnrloc; /* FNR */
extern Cell *fsloc; /* FS */
extern Cell *nfloc; /* NF */
extern Cell *ofsloc; /* OFS */
extern Cell *orsloc; /* ORS */
extern Cell *rsloc; /* RS */
extern Cell *rstartloc; /* RSTART */
extern Cell *rlengthloc; /* RLENGTH */
extern Cell *subseploc; /* SUBSEP */
/* Cell.tval values: */
#define NUM 01 /* number value is valid */

10
b.c
View File

@ -824,7 +824,15 @@ int relex(void) /* lexical analyzer for reparse */
if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' &&
prestr[2 + cc->cc_namelen] == ']') {
prestr += cc->cc_namelen + 3;
for (i = 0; i <= UCHAR_MAX; i++) {
/*
* BUG: We begin at 1, instead of 0, since we
* would otherwise prematurely terminate the
* string for classes like [[:cntrl:]]. This
* means that we can't match the NUL character,
* not without first adapting the entire
* program to track each string's length.
*/
for (i = 1; i <= UCHAR_MAX; i++) {
if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, "relex2"))
FATAL("out of space for reg expr %.10s...", lastre);
if (cc->cc_func(i)) {

View File

@ -23,3 +23,32 @@ and also if CONVFMT changed.
7. unary-plus: Unary plus on a string constant returned the string.
Instead, it should convert the value to numeric and give that value.
8. concat-assign-same: Concatenation previously evaluated both sides of the
expression before doing its work, which, since assign() evaluates to the cell
being assigned to, meant that expressions like "print (a = 1) (a = 2)" would
print "22" rather than "12".
9. missing-precision: When using the format string "%*s", the precision
argument was used without checking if it was present first.
10. missing-precision: When using the format string "%*s", the precision
argument was used without checking if it was present first.
11. fmt-overflow: The buffer used for OFMT/CONVFMT conversions was written
to with sprintf(), which meant that some conversions could write past the
end.
12. numeric-subsep, numeric-fs, numeric-output-seps, numerics-rs: If SUBSEP,
FS, RS, OFS, or ORS were set to a numeric value, then their string values
wouldn't always be generated before being needed.
13. subsep-overflow: The length of SUBSEP needs to be rechecked after
calling execute(), in case SUBSEP itself has been changed.
14. split-fs-from-array: If the third argument to split() comes from the
array passed as the second argument, then split() would previously read
from the freed memory and possibly produce incorrect results (depending
on the system's malloc()/free() behaviour.)

View File

@ -0,0 +1,4 @@
BEGIN {
print (a = 1) (a = 2) (a = 3) (a = 4) (a = 5);
print (a = 1), (a = 2), (a = 3), (a = 4), (a = 5);
}

View File

@ -0,0 +1,2 @@
22345
1 2 3 4 5

View File

@ -0,0 +1,2 @@
12345
1 2 3 4 5

View File

@ -0,0 +1 @@
BEGIN { OFMT = "%.1000f"; print 1.25; }

View File

@ -0,0 +1 @@
1.2500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

View File

@ -0,0 +1,13 @@
function foo() {
a = "";
for (i = 0; i < 10000; i++) {
a = a "c";
}
return a;
}
BEGIN {
FS = foo();
$0="foo";
print $1;
}

View File

@ -0,0 +1 @@
BEGIN { printf("%*s"); }

View File

@ -0,0 +1,2 @@
./a.out: not enough args in printf(%*s)
source line number 1

View File

@ -0,0 +1 @@
BEGIN { NF = -5; }

View File

@ -0,0 +1,2 @@
./a.out: cannot set NF to a negative value
source line number 1

View File

@ -0,0 +1,6 @@
BEGIN {
$0="a b c";
OFS=",";
NF = NF;
print;
}

View File

@ -0,0 +1 @@
a b c

View File

@ -0,0 +1 @@
a,b,c

View File

@ -0,0 +1,5 @@
BEGIN {
FS = 0; split("20202", a); print a[1];
FS = 1; $0="31313"; print $1;
FS = 2; "echo 42424" | getline; print $1;
}

3
bugs-fixed/numeric-fs.ok Normal file
View File

@ -0,0 +1,3 @@
2
3
4

View File

@ -0,0 +1,8 @@
BEGIN {
$0 = "a b c";
OFS = 1;
ORS = 2;
NF = 2;
print;
print "d", "e";
}

View File

@ -0,0 +1,2 @@
a b
d e

View File

@ -0,0 +1 @@
a1b2d1e2

View File

@ -0,0 +1,6 @@
BEGIN {
RS = 1;
while ("echo a1b1c1d" | getline > 0) {
print $1;
}
}

View File

@ -0,0 +1 @@
a1b1c1d

4
bugs-fixed/numeric-rs.ok Normal file
View File

@ -0,0 +1,4 @@
a
b
c
d

View File

@ -0,0 +1,5 @@
BEGIN {
SUBSEP = 123.456;
a["hello", "world"] = "foo";
print a["hello" SUBSEP "world"];
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
foo

View File

@ -0,0 +1,5 @@
BEGIN {
a[1] = "elephantie"
a[2] = "e"
print split(a[1],a,a[2]), a[2], a[3], split(a[2],a,a[2])
}

View File

@ -0,0 +1 @@
4 l phanti 2

View File

@ -0,0 +1,24 @@
function foo(c, n) {
s = "";
for (i = 0; i < n; i++) {
s = s c;
}
return s;
}
BEGIN {
str1 = foo("a", 4500);
str2 = foo("b", 9000);
a[(SUBSEP = str1), (SUBSEP = str2), "c"] = 1;
for (k in a) {
print length(k);
}
print (((SUBSEP = str1), (SUBSEP = str2), "c") in a);
print (((SUBSEP = str1) SUBSEP (SUBSEP = str2) SUBSEP "c") in a);
delete a[(SUBSEP = str1), (SUBSEP = str2), "c"];
print (((SUBSEP = str1), (SUBSEP = str2), "c") in a);
print (((SUBSEP = str1) SUBSEP (SUBSEP = str2) SUBSEP "c") in a);
}

View File

@ -0,0 +1,5 @@
27001
1
1
0
0

18
lex.c
View File

@ -198,6 +198,7 @@ int yylex(void)
yylval.i = c;
switch (c) {
case '\n': /* {EOL} */
lineno++;
RET(NL);
case '\r': /* assume \n is coming */
case ' ': /* {WS}+ */
@ -213,6 +214,7 @@ int yylex(void)
case '\\':
if (peek() == '\n') {
input();
lineno++;
} else if (peek() == '\r') {
input(); input(); /* \n */
lineno++;
@ -370,10 +372,11 @@ int string(void)
case '\n':
case '\r':
case 0:
*bp = '\0';
SYNTAX( "non-terminated string %.10s...", buf );
lineno++;
if (c == 0) /* hopeless */
FATAL( "giving up" );
lineno++;
break;
case '\\':
c = input();
@ -515,6 +518,7 @@ int regexpr(void)
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr"))
FATAL("out of space for reg expr %.10s...", buf);
if (c == '\n') {
*bp = '\0';
SYNTAX( "newline in regular expression %.10s...", buf );
unput('\n');
break;
@ -553,19 +557,19 @@ int input(void) /* get next lexical input character */
lexprog++;
} else /* awk -f ... */
c = pgetc();
if (c == '\n')
lineno++;
else if (c == EOF)
if (c == EOF)
c = 0;
if (ep >= ebuf + sizeof ebuf)
ep = ebuf;
return *ep++ = c;
*ep = c;
if (c != 0) {
ep++;
}
return (c);
}
void unput(int c) /* put lexical character back on input */
{
if (c == '\n')
lineno--;
if (yysptr >= yysbuf + sizeof(yysbuf))
FATAL("pushed back too much: %.20s...", yysbuf);
*yysptr++ = c;

18
lib.c
View File

@ -59,7 +59,7 @@ void recinit(unsigned int n)
{
if ( (record = (char *) malloc(n)) == NULL
|| (fields = (char *) malloc(n+1)) == NULL
|| (fldtab = (Cell **) malloc((nfields+1) * sizeof(Cell *))) == NULL
|| (fldtab = (Cell **) malloc((nfields+2) * sizeof(Cell *))) == NULL
|| (fldtab[0] = (Cell *) malloc(sizeof(Cell))) == NULL )
FATAL("out of space for $0 and fields");
*fldtab[0] = dollar0;
@ -189,12 +189,13 @@ int readrec(char **pbuf, int *pbufsize, FILE *inf) /* read one record into buf *
int sep, c;
char *rr, *buf = *pbuf;
int bufsize = *pbufsize;
char *rs = getsval(rsloc);
if (strlen(*FS) >= sizeof(inputFS))
if (strlen(getsval(fsloc)) >= sizeof (inputFS))
FATAL("field separator %.10s... is too long", *FS);
/*fflush(stdout); avoids some buffering problem but makes it 25% slower*/
strcpy(inputFS, *FS); /* for subsequent field splitting */
if ((sep = **RS) == 0) {
if ((sep = *rs) == 0) {
sep = '\n';
while ((c=getc(inf)) == '\n' && c != EOF) /* skip leading \n's */
;
@ -208,7 +209,7 @@ int readrec(char **pbuf, int *pbufsize, FILE *inf) /* read one record into buf *
FATAL("input record `%.30s...' too long", buf);
*rr++ = c;
}
if (**RS == sep || c == EOF)
if (*rs == sep || c == EOF)
break;
if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
break;
@ -283,6 +284,8 @@ void fldbld(void) /* create fields from current record */
}
fr = fields;
i = 0; /* number of fields accumulated here */
if (strlen(getsval(fsloc)) >= sizeof (inputFS))
FATAL("field separator %.10s... is too long", *FS);
strcpy(inputFS, *FS);
if (strlen(inputFS) > 1) { /* it's a regular expression */
i = refldbld(r, inputFS);
@ -390,6 +393,8 @@ void newfld(int n) /* add field n after end of existing lastfld */
void setlastfld(int n) /* set lastfld cleaning fldtab cells if necessary */
{
if (n < 0)
FATAL("cannot set NF to a negative value");
if (n > nfields)
growfldtab(n);
@ -479,6 +484,7 @@ void recbld(void) /* create $0 from $1..$NF if necessary */
{
int i;
char *r, *p;
char *sep = getsval(ofsloc);
if (donerec == 1)
return;
@ -490,9 +496,9 @@ void recbld(void) /* create $0 from $1..$NF if necessary */
while ((*r = *p++) != 0)
r++;
if (i < *NF) {
if (!adjbuf(&record, &recsize, 2+strlen(*OFS)+r-record, recsize, &r, "recbld 2"))
if (!adjbuf(&record, &recsize, 2+strlen(sep)+r-record, recsize, &r, "recbld 2"))
FATAL("created $0 `%.30s...' too long", record);
for (p = *OFS; (*r = *p++) != 0; )
for (p = sep; (*r = *p++) != 0; )
r++;
}
}

2
main.c
View File

@ -88,7 +88,7 @@ int main(int argc, char *argv[])
exit(0);
break;
}
if (strncmp(argv[1], "--", 2) == 0) { /* explicit end of args */
if (strcmp(argv[1], "--") == 0) { /* explicit end of args */
argc--;
argv++;
break;

View File

@ -34,8 +34,8 @@ CC = gcc -g -Wall -pedantic
# yacc options. pick one; this varies a lot by system.
#YFLAGS = -d -S
#YACC = bison -d -y
YACC = yacc -d
YACC = bison -d -y
#YACC = yacc -d
# -S uses sprintf in yacc parser instead of sprint
OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o
@ -54,10 +54,15 @@ a.out: ytab.o $(OFILES)
$(OFILES): awk.h ytab.h proto.h
ytab.c: awk.h proto.h awkgram.y
#Clear dependency for parallel build: (make -j)
#YACC generated y.tab.c and y.tab.h at the same time
#this needs to be a static pattern rules otherwise multiple target
#are mapped onto multiple executions of yacc, which overwrite
#each others outputs.
y%.c y%.h: awk.h proto.h awkgram.y
$(YACC) $(YFLAGS) awkgram.y
mv y.tab.c ytab.c
mv y.tab.h ytab.h
mv y.$*.c y$*.c
mv y.$*.h y$*.h
ytab.h: ytab.c

View File

@ -135,6 +135,8 @@ int main(int argc, char *argv[])
n = sscanf(buf, "%1c %s %s %d", &c, def, name, &tok);
if (c != '#' || (n != 4 && strcmp(def,"define") != 0)) /* not a valid #define */
continue;
if (strcmp(name, "YYSTYPE_IS_DECLARED") == 0)
continue;
if (tok < FIRSTTOKEN || tok > LASTTOKEN) {
/* fprintf(stderr, "maketab funny token %d %s ignored\n", tok, buf); */
continue;

57
run.c
View File

@ -462,7 +462,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
Node *np;
char *buf;
int bufsz = recsize;
int nsub = strlen(*SUBSEP);
int nsub;
if ((buf = (char *) malloc(bufsz)) == NULL)
FATAL("out of memory in array");
@ -472,6 +472,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
for (np = a[1]; np; np = np->nnext) {
y = execute(np); /* subscript */
s = getsval(y);
nsub = strlen(getsval(subseploc));
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "array"))
FATAL("out of memory for %s[%s...]", x->nval, buf);
strcat(buf, s);
@ -500,7 +501,7 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
Cell *x, *y;
Node *np;
char *s;
int nsub = strlen(*SUBSEP);
int nsub;
x = execute(a[0]); /* Cell* for symbol table */
if (!isarr(x))
@ -519,9 +520,10 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
for (np = a[1]; np; np = np->nnext) {
y = execute(np); /* subscript */
s = getsval(y);
nsub = strlen(getsval(subseploc));
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "awkdelete"))
FATAL("out of memory deleting %s[%s...]", x->nval, buf);
strcat(buf, s);
strcat(buf, s);
if (np->nnext)
strcat(buf, *SUBSEP);
tempfree(y);
@ -540,7 +542,7 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
char *buf;
char *s;
int bufsz = recsize;
int nsub = strlen(*SUBSEP);
int nsub;
ap = execute(a[1]); /* array name */
if (!isarr(ap)) {
@ -558,6 +560,7 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
for (p = a[0]; p; p = p->nnext) {
x = execute(p); /* expr */
s = getsval(x);
nsub = strlen(getsval(subseploc));
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "intest"))
FATAL("out of memory deleting %s[%s...]", x->nval, buf);
strcat(buf, s);
@ -863,6 +866,9 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
FATAL("'$' not permitted in awk formats");
}
if (*s == '*') {
if (a == NULL) {
FATAL("not enough args in printf(%s)", os);
}
x = execute(a);
a = a->nnext;
sprintf(t-1, "%d", fmtwd=(int) getfval(x));
@ -1117,8 +1123,8 @@ Cell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */
y = execute(a[1]);
x = execute(a[0]);
if (n == ASSIGN) { /* ordinary assignment */
if (x == y && !(x->tval & (FLD|REC))) /* self-assignment: */
; /* leave alone unless it's a field */
if (x == y && !(x->tval & (FLD|REC)) && x != nfloc)
; /* self-assignment: leave alone unless it's a field or NF */
else if ((y->tval & (STR|NUM)) == (STR|NUM)) {
setsval(x, getsval(y));
x->fval = getfval(y);
@ -1175,25 +1181,26 @@ Cell *cat(Node **a, int q) /* a[0] cat a[1] */
{
Cell *x, *y, *z;
int n1, n2;
char *s;
char *s = NULL;
int ssz = 0;
x = execute(a[0]);
n1 = strlen(getsval(x));
adjbuf(&s, &ssz, n1 + 1, recsize, 0, "cat1");
(void) strncpy(s, x->sval, ssz);
y = execute(a[1]);
getsval(x);
getsval(y);
n1 = strlen(x->sval);
n2 = strlen(y->sval);
s = (char *) malloc(n1 + n2 + 1);
if (s == NULL)
FATAL("out of space concatenating %.15s... and %.15s...",
x->sval, y->sval);
strcpy(s, x->sval);
strcpy(s+n1, y->sval);
n2 = strlen(getsval(y));
adjbuf(&s, &ssz, n1 + n2 + 1, recsize, 0, "cat2");
(void) strncpy(s + n1, y->sval, ssz - n1);
tempfree(x);
tempfree(y);
z = gettemp();
z->sval = s;
z->tval = STR;
return(z);
}
@ -1240,18 +1247,20 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
{
Cell *x = 0, *y, *ap;
char *s, *origs;
char *fs, *origfs = NULL;
int sep;
char *t, temp, num[50], *fs = 0;
char *t, temp, num[50];
int n, tempstat, arg3type;
y = execute(a[0]); /* source string */
origs = s = strdup(getsval(y));
arg3type = ptoi(a[3]);
if (a[2] == 0) /* fs string */
fs = *FS;
fs = getsval(fsloc);
else if (arg3type == STRING) { /* split(str,arr,"string") */
x = execute(a[2]);
fs = getsval(x);
origfs = fs = strdup(getsval(x));
tempfree(x);
} else if (arg3type == REGEXPR)
fs = "(regexpr)"; /* split(str,arr,/regexpr/) */
else
@ -1366,9 +1375,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
tempfree(ap);
tempfree(y);
free(origs);
if (a[2] != 0 && arg3type == STRING) {
tempfree(x);
}
free(origfs);
x = gettemp();
x->tval = NUM;
x->fval = n;
@ -1630,9 +1637,9 @@ Cell *printstat(Node **a, int n) /* print a[0] */
fputs(getpssval(y), fp);
tempfree(y);
if (x->nnext == NULL)
fputs(*ORS, fp);
fputs(getsval(orsloc), fp);
else
fputs(*OFS, fp);
fputs(getsval(ofsloc), fp);
}
if (a[1] != 0)
fflush(fp);

27
tran.c
View File

@ -55,10 +55,14 @@ Cell *fsloc; /* FS */
Cell *nrloc; /* NR */
Cell *nfloc; /* NF */
Cell *fnrloc; /* FNR */
Cell *ofsloc; /* OFS */
Cell *orsloc; /* ORS */
Cell *rsloc; /* RS */
Array *ARGVtab; /* symbol table containing ARGV[...] */
Array *ENVtab; /* symbol table containing ENVIRON[...] */
Cell *rstartloc; /* RSTART */
Cell *rlengthloc; /* RLENGTH */
Cell *subseploc; /* SUBSEP */
Cell *symtabloc; /* SYMTAB */
Cell *nullloc; /* a guaranteed empty cell */
@ -88,9 +92,12 @@ void syminit(void) /* initialize symbol table with builtin vars */
fsloc = setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab);
FS = &fsloc->sval;
RS = &setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
OFS = &setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab)->sval;
ORS = &setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
rsloc = setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab);
RS = &rsloc->sval;
ofsloc = setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab);
OFS = &ofsloc->sval;
orsloc = setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab);
ORS = &orsloc->sval;
OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
CONVFMT = &setsymtab("CONVFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
FILENAME = &setsymtab("FILENAME", "", 0.0, STR|DONTFREE, symtab)->sval;
@ -100,7 +107,8 @@ void syminit(void) /* initialize symbol table with builtin vars */
NR = &nrloc->fval;
fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab);
FNR = &fnrloc->fval;
SUBSEP = &setsymtab("SUBSEP", "\034", 0.0, STR|DONTFREE, symtab)->sval;
subseploc = setsymtab("SUBSEP", "\034", 0.0, STR|DONTFREE, symtab);
SUBSEP = &subseploc->sval;
rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab);
RSTART = &rstartloc->fval;
rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab);
@ -310,6 +318,9 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
} else if (isrec(vp)) {
donefld = 0; /* mark $1... invalid */
donerec = 1;
} else if (vp == ofsloc) {
if (donerec == 0)
recbld();
}
if (freeable(vp))
xfree(vp->sval); /* free any previous string */
@ -351,7 +362,7 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
} else if (isrec(vp)) {
donefld = 0; /* mark $1... invalid */
donerec = 1;
} else if (&vp->sval == OFS) {
} else if (vp == ofsloc) {
if (donerec == 0)
recbld();
}
@ -395,7 +406,7 @@ Awkfloat getfval(Cell *vp) /* get float val of a Cell */
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
{
char s[100]; /* BUG: unchecked */
char s[256];
double dtemp;
if ((vp->tval & (NUM | STR)) == 0)
@ -434,9 +445,9 @@ static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cel
if (freeable(vp)) \
xfree(vp->sval); \
if (modf(vp->fval, &dtemp) == 0) /* it's integral */ \
sprintf(s, "%.30g", vp->fval); \
snprintf(s, sizeof (s), "%.30g", vp->fval); \
else \
sprintf(s, *fmt, vp->fval); \
snprintf(s, sizeof (s), *fmt, vp->fval); \
vp->sval = tostring(s); \
vp->tval &= ~DONTFREE; \
vp->tval |= STR; \