summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2004-12-30 01:52:49 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2004-12-30 01:52:49 +0000
commit92f3150912b4d375df827a15d8e929575c71c014 (patch)
treef638bbe716809fd27621b25c2813a1e9478a88bc /usr.bin
parent0f3aec300d9d954add1864f9c69be31ab4f02569 (diff)
Update to version 20041222; OK deraadt@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/awk/FIXES97
-rw-r--r--usr.bin/awk/Makefile4
-rw-r--r--usr.bin/awk/README14
-rw-r--r--usr.bin/awk/awk.h6
-rw-r--r--usr.bin/awk/b.c81
-rw-r--r--usr.bin/awk/lex.c11
-rw-r--r--usr.bin/awk/lib.c23
-rw-r--r--usr.bin/awk/main.c7
-rw-r--r--usr.bin/awk/run.c26
-rw-r--r--usr.bin/awk/tran.c15
10 files changed, 230 insertions, 54 deletions
diff --git a/usr.bin/awk/FIXES b/usr.bin/awk/FIXES
index a2901b4952a..48ad1a8f200 100644
--- a/usr.bin/awk/FIXES
+++ b/usr.bin/awk/FIXES
@@ -1,4 +1,4 @@
-/* $OpenBSD: FIXES,v 1.12 2003/11/09 20:13:57 otto Exp $ */
+/* $OpenBSD: FIXES,v 1.13 2004/12/30 01:52:48 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -26,6 +26,101 @@ THIS SOFTWARE.
This file lists all bug fixes, changes, etc., made since the AWK book
was sent to the printers in August, 1987.
+Dec 22, 2004:
+ cranked up size of NCHARS; coverity thinks it can be overrun with
+ smaller size, and i think that's right. added some assertions to b.c
+ to catch places where it might overrun. the RE code is still fragile.
+
+Dec 5, 2004:
+ fixed a couple of overflow problems with ridiculous field numbers:
+ e.g., print $(2^32-1). thanks to ruslan ermilov, giorgos keramidas
+ and david o'brien at freebsd.org for patches. this really should
+ be re-done from scratch.
+
+Nov 21, 2004:
+ fixed another 25-year-old RE bug, in split. it's another failure
+ to (re-)initialize. thanks to steve fisher for spotting this and
+ providing a good test case.
+
+Nov 22, 2003:
+ fixed a bug in regular expressions that dates (so help me) from 1977;
+ it's been there from the beginning. an anchored longest match that
+ was longer than the number of states triggered a failure to initialize
+ the machine properly. many thanks to moinak ghosh for not only finding
+ this one but for providing a fix, in some of the most mysterious
+ code known to man.
+
+ fixed a storage leak in call() that appears to have been there since
+ 1983 or so -- a function without an explicit return that assigns a
+ string to a parameter leaked a Cell. thanks to moinak ghosh for
+ spotting this very subtle one.
+
+Jul 31, 2003:
+ fixed, thanks to andrey chernov and ruslan ermilov, a bug in lex.c
+ that mis-handled the character 255 in input. (it was being compared
+ to EOF with a signed comparison.)
+
+Jul 29, 2003:
+ fixed (i think) the long-standing botch that included the beginning of
+ line state ^ for RE's in the set of valid characters; this led to a
+ variety of odd problems, including failure to properly match certain
+ regular expressions in non-US locales. thanks to ruslan for keeping
+ at this one.
+
+Jul 28, 2003:
+ n-th try at getting internationalization right, with thanks to volker
+ kiefel, arnold robbins and ruslan ermilov for advice, though they
+ should not be blamed for the outcome. according to posix, "." is the
+ radix character in programs and command line arguments regardless of
+ the locale; otherwise, the locale should prevail for input and output
+ of numbers. so it's intended to work that way.
+
+ i have rescinded the attempt to use strcoll in expanding shorthands in
+ regular expressions (cclenter). its properties are much too
+ surprising; for example [a-c] matches aAbBc in locale en_US but abBcC
+ in locale fr_CA. i can see how this might arise by implementation
+ but i cannot explain it to a human user. (this behavior can be seen
+ in gawk as well; we're leaning on the same library.)
+
+ the issue appears to be that strcoll is meant for sorting, where
+ merging upper and lower case may make sense (though note that unix
+ sort does not do this by default either). it is not appropriate
+ for regular expressions, where the goal is to match specific
+ patterns of characters. in any case, the notations [:lower:], etc.,
+ are available in awk, and they are more likely to work correctly in
+ most locales.
+
+ a moratorium is hereby declared on internationalization changes.
+ i apologize to friends and colleagues in other parts of the world.
+ i would truly like to get this "right", but i don't know what
+ that is, and i do not want to keep making changes until it's clear.
+
+Jul 4, 2003:
+ fixed bug that permitted non-terminated RE, as in "awk /x".
+
+Jun 1, 2003:
+ subtle change to split: if source is empty, number of elems
+ is always 0 and the array is not set.
+
+Mar 21, 2003:
+ added some parens to isblank, in another attempt to make things
+ internationally portable.
+
+Mar 14, 2003:
+ the internationalization changes, somewhat modified, are now
+ reinstated. in theory awk will now do character comparisons
+ and case conversions in national language, but "." will always
+ be the decimal point separator on input and output regardless
+ of national language. isblank(){} has an #ifndef.
+
+ this no longer compiles on windows: LC_MESSAGES isn't defined
+ in vc6++.
+
+ fixed subtle behavior in field and record splitting: if FS is
+ a single character and RS is not empty, \n is NOT a separator.
+ this tortuous reading is found in the awk book; behavior now
+ matches gawk and mawk.
+
Dec 13, 2002:
for the moment, the internationalization changes of nov 29 are
rolled back -- programs like x = 1.2 don't work in some locales,
diff --git a/usr.bin/awk/Makefile b/usr.bin/awk/Makefile
index e6e1a177176..92220707a06 100644
--- a/usr.bin/awk/Makefile
+++ b/usr.bin/awk/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.6 2003/12/14 16:00:37 jmc Exp $
+# $OpenBSD: Makefile,v 1.7 2004/12/30 01:52:48 millert Exp $
PROG= awk
LINKS= ${BINDIR}/awk ${BINDIR}/nawk
@@ -6,7 +6,7 @@ SRCS= ytab.c lex.c b.c main.c parse.c proctab.c tran.c lib.c run.c
LDADD= -lm
DPADD= ${LIBM}
CLEANFILES+=proctab.c maketab ytab.c ytab.h
-CFLAGS+=-I. -I${.CURDIR}
+CFLAGS+=-I. -I${.CURDIR} -DHAS_ISBLANK -DNDEBUG
MLINKS= awk.1 nawk.1
# This just gets installed verbatim
diff --git a/usr.bin/awk/README b/usr.bin/awk/README
index 308fddfee50..a54b689450e 100644
--- a/usr.bin/awk/README
+++ b/usr.bin/awk/README
@@ -1,4 +1,4 @@
-/* $OpenBSD: README,v 1.5 2002/12/19 21:24:28 millert Exp $ */
+/* $OpenBSD: README,v 1.6 2004/12/30 01:52:48 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -57,7 +57,7 @@ conflicts: 43 shift/reduce, 85 reduce/reduce
This produces an executable a.out; you will eventually want to
move this to some place like /usr/bin/awk.
-If your system is does not have yacc or bison (the GNU
+If your system does not have yacc or bison (the GNU
equivalent), you must compile the pieces manually. We have
included yacc output in ytab.c and ytab.h, and backup copies in
case you overwrite them. We have also included a copy of
@@ -73,8 +73,14 @@ This also compiles with Visual C++ on all flavors of Windows,
*if* you provide versions of popen and pclose. The file
missing95.c contains versions that can be used to get started
with, though the underlying support has mysterious properties,
-the symptom of which can be truncated pipe output. Beware.
-The file makefile.win gives hints on how to proceed.
+the symptom of which can be truncated pipe output. Beware. The
+file makefile.win gives hints on how to proceed; if you run
+vcvars32.bat, it will set up necessary paths and parameters so
+you can subsequently run nmake -f makefile.win. Beware also that
+when running on Windows under command.com, various quoting
+conventions are different from Unix systems: single quotes won't
+work around arguments, and various characters like % are
+interpreted within double quotes.
This compiles without change on Macintosh OS X using gcc and
the standard developer tools.
diff --git a/usr.bin/awk/awk.h b/usr.bin/awk/awk.h
index e29804c8c83..2159f662d9f 100644
--- a/usr.bin/awk/awk.h
+++ b/usr.bin/awk/awk.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: awk.h,v 1.10 2002/12/19 21:24:28 millert Exp $ */
+/* $OpenBSD: awk.h,v 1.11 2004/12/30 01:52:48 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -23,6 +23,8 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
+#include <assert.h>
+
typedef double Awkfloat;
/* unsigned char is more trouble than it's worth */
@@ -200,7 +202,7 @@ extern int pairstack[], paircnt;
/* structures used by regular expression matching machinery, mostly b.c: */
-#define NCHARS (256+1) /* 256 handles 8-bit chars; 128 does 7-bit */
+#define NCHARS (256+3) /* 256 handles 8-bit chars; 128 does 7-bit */
/* watch out in match(), etc. */
#define NSTATES 32
diff --git a/usr.bin/awk/b.c b/usr.bin/awk/b.c
index c6039e6740b..a3a4ee4eedc 100644
--- a/usr.bin/awk/b.c
+++ b/usr.bin/awk/b.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: b.c,v 1.11 2002/12/19 21:24:28 millert Exp $ */
+/* $OpenBSD: b.c,v 1.12 2004/12/30 01:52:48 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -34,7 +34,7 @@ THIS SOFTWARE.
#include "awk.h"
#include "ytab.h"
-#define HAT (NCHARS-2) /* matches ^ in regular expr */
+#define HAT (NCHARS+2) /* matches ^ in regular expr */
/* NCHARS is 2**n */
#define MAXLIN 22
@@ -466,6 +466,7 @@ int match(fa *f, const char *p0) /* shortest match ? */
if (f->out[s])
return(1);
do {
+ assert(*p < NCHARS);
if ((ns = f->gototab[s][*p]) != 0)
s = ns;
else
@@ -483,7 +484,12 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
uschar *q;
int i, k;
- s = f->reset ? makeinit(f,1) : f->initstat;
+ /* s = f->reset ? makeinit(f,1) : f->initstat; */
+ if (f->reset) {
+ f->initstat = s = makeinit(f,1);
+ } else {
+ s = f->initstat;
+ }
patbeg = (char *) p;
patlen = -1;
do {
@@ -491,6 +497,7 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
do {
if (f->out[s]) /* final state */
patlen = q-p;
+ assert(*q < NCHARS);
if ((ns = f->gototab[s][*q]) != 0)
s = ns;
else
@@ -536,13 +543,19 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
uschar *q;
int i, k;
- s = f->reset ? makeinit(f,1) : f->initstat;
+ /* s = f->reset ? makeinit(f,1) : f->initstat; */
+ if (f->reset) {
+ f->initstat = s = makeinit(f,1);
+ } else {
+ s = f->initstat;
+ }
patlen = -1;
while (*p) {
q = p;
do {
if (f->out[s]) /* final state */
patlen = q-p;
+ assert(*q < NCHARS);
if ((ns = f->gototab[s][*q]) != 0)
s = ns;
else
@@ -696,23 +709,42 @@ Node *unary(Node *np)
* relex(), the expanded character class (prior to range expansion)
* must be less than twice the size of their full name.
*/
+
+/* Because isblank doesn't show up in any of the header files on any
+ * system i use, it's defined here. if some other locale has a richer
+ * definition of "blank", define HAS_ISBLANK and provide your own
+ * version.
+ * the parentheses here are an attempt to find a path through the maze
+ * of macro definition and/or function and/or version provided. thanks
+ * to nelson beebe for the suggestion; let's see if it works everywhere.
+ */
+
+#ifndef HAS_ISBLANK
+
+int (isblank)(int c)
+{
+ return c==' ' || c=='\t';
+}
+
+#endif
+
struct charclass {
const char *cc_name;
int cc_namelen;
- const char *cc_expand;
+ int (*cc_func)(int);
} charclasses[] = {
- { "alnum", 5, "0-9A-Za-z" },
- { "alpha", 5, "A-Za-z" },
- { "blank", 5, " \t" },
- { "cntrl", 5, "\000-\037\177" },
- { "digit", 5, "0-9" },
- { "graph", 5, "\041-\176" },
- { "lower", 5, "a-z" },
- { "print", 5, " \041-\176" },
- { "punct", 5, "\041-\057\072-\100\133-\140\173-\176" },
- { "space", 5, " \f\n\r\t\v" },
- { "upper", 5, "A-Z" },
- { "xdigit", 6, "0-9A-Fa-f" },
+ { "alnum", 5, isalnum },
+ { "alpha", 5, isalpha },
+ { "blank", 5, isblank },
+ { "cntrl", 5, iscntrl },
+ { "digit", 5, isdigit },
+ { "graph", 5, isgraph },
+ { "lower", 5, islower },
+ { "print", 5, isprint },
+ { "punct", 5, ispunct },
+ { "space", 5, isspace },
+ { "upper", 5, isupper },
+ { "xdigit", 6, isxdigit },
{ NULL, 0, NULL },
};
@@ -725,7 +757,7 @@ int relex(void) /* lexical analyzer for reparse */
static int bufsz = 100;
uschar *bp;
struct charclass *cc;
- const uschar *p;
+ int i;
switch (c = *prestr++) {
case '|': return OR;
@@ -774,8 +806,14 @@ 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 (p = (const uschar *) cc->cc_expand; *p; p++)
- *bp++ = *p;
+ for (i = 0; i < NCHARS; i++) {
+ if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, 0))
+ FATAL("out of space for reg expr %.10s...", lastre);
+ if (cc->cc_func(i)) {
+ *bp++ = i;
+ n++;
+ }
+ }
} else
*bp++ = c;
} else if (c == '\0') {
@@ -800,8 +838,7 @@ int cgoto(fa *f, int s, int c)
int i, j, k;
int *p, *q;
- if (c < 0 || c > 255)
- FATAL("can't happen: neg char %d in cgoto", c);
+ assert(c == HAT || c < NCHARS);
while (f->accept >= maxsetvec) { /* guessing here! */
maxsetvec *= 4;
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
diff --git a/usr.bin/awk/lex.c b/usr.bin/awk/lex.c
index 49471d46f5c..737f589ea66 100644
--- a/usr.bin/awk/lex.c
+++ b/usr.bin/awk/lex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lex.c,v 1.7 2003/07/02 21:04:09 deraadt Exp $ */
+/* $OpenBSD: lex.c,v 1.8 2004/12/30 01:52:48 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -157,6 +157,7 @@ int gettok(char **pbuf, int *psz) /* get next input token */
*bp = 0;
strtod(buf, &rem); /* parse the number */
unputstr(rem); /* put rest back for later */
+/* printf("unputstr [%s], buf [%s]\n", rem, buf); */
if (rem == buf) { /* it wasn't a valid number at all */
buf[1] = 0; /* so return one character as token */
retc = buf[0]; /* character is its own type */
@@ -192,8 +193,10 @@ int yylex(void)
reg = 0;
return regexpr();
}
+/* printf("top\n"); */
for (;;) {
c = gettok(&buf, &bufsize);
+/* printf("gettok [%s]\n", buf); */
if (c == 0)
return 0;
if (isalpha(c) || c == '_')
@@ -534,6 +537,8 @@ int regexpr(void)
}
}
*bp = 0;
+ if (c == 0)
+ SYNTAX("non-terminated regular expression %.10s...", buf);
yylval.s = tostring(buf);
unput('/');
RET(REGEXPR);
@@ -553,9 +558,9 @@ int input(void) /* get next lexical input character */
extern char *lexprog;
if (yysptr > yysbuf)
- c = *--yysptr;
+ c = (uschar)*--yysptr;
else if (lexprog != NULL) { /* awk '...' */
- if ((c = *lexprog) != 0)
+ if ((c = (uschar)*lexprog) != 0)
lexprog++;
} else /* awk -f ... */
c = pgetc();
diff --git a/usr.bin/awk/lib.c b/usr.bin/awk/lib.c
index 51a1845c58c..8b969b78f48 100644
--- a/usr.bin/awk/lib.c
+++ b/usr.bin/awk/lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lib.c,v 1.14 2003/12/01 15:34:26 grange Exp $ */
+/* $OpenBSD: lib.c,v 1.15 2004/12/30 01:52:48 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -105,10 +105,11 @@ void initgetrec(void)
infile = stdin; /* no filenames, so use stdin */
}
+static int firsttime = 1;
+
int getrec(char **pbuf, int *pbufsize, int isrecord) /* get next input record */
{ /* note: cares whether buf == record */
int c;
- static int firsttime = 1;
char *buf = *pbuf;
int bufsize = *pbufsize;
@@ -312,6 +313,13 @@ void fldbld(void) /* create fields from current record */
}
*fr = 0;
} else if (*r != 0) { /* if 0, it's a null field */
+ /* subtlecase : if length(FS) == 1 && length(RS > 0)
+ * \n is NOT a field separator (cf awk book 61,84).
+ * this variable is tested in the inner while loop.
+ */
+ int rtest = '\n'; /* normal case */
+ if (strlen(*RS) > 0)
+ rtest = '\0';
for (;;) {
i++;
if (i > nfields)
@@ -320,7 +328,7 @@ void fldbld(void) /* create fields from current record */
xfree(fldtab[i]->sval);
fldtab[i]->sval = fr;
fldtab[i]->tval = FLD | STR | DONTFREE;
- while (*r != sep && *r != '\n' && *r != '\0') /* \n is always a separator */
+ while (*r != sep && *r != rtest && *r != '\0') /* \n is always a separator */
*fr++ = *r++;
*fr++ = 0;
if (*r++ == 0)
@@ -375,7 +383,7 @@ void newfld(int n) /* add field n after end of existing lastfld */
Cell *fieldadr(int n) /* get nth field */
{
if (n < 0)
- FATAL("trying to access field %d", n);
+ FATAL("trying to access out of range field %d", n);
if (n > nfields) /* fields after NF are empty */
growfldtab(n); /* but does not increase NF */
return(fldtab[n]);
@@ -384,10 +392,15 @@ Cell *fieldadr(int n) /* get nth field */
void growfldtab(int n) /* make new fields up to at least $n */
{
int nf = 2 * nfields;
+ size_t s;
if (n > nf)
nf = n;
- fldtab = (Cell **) realloc(fldtab, (nf+1) * (sizeof (struct Cell *)));
+ s = (nf+1) * (sizeof (struct Cell *)); /* freebsd: how much do we need? */
+ if (s / sizeof(struct Cell *) - 1 == nf) /* didn't overflow */
+ fldtab = (Cell **) realloc(fldtab, s);
+ else /* overflow sizeof int */
+ xfree(fldtab); /* make it null */
if (fldtab == NULL)
FATAL("out of space creating %d fields", nf);
makefields(nfields+1, nf);
diff --git a/usr.bin/awk/main.c b/usr.bin/awk/main.c
index 40ed2624efc..6dc93f9709b 100644
--- a/usr.bin/awk/main.c
+++ b/usr.bin/awk/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.12 2002/12/19 21:24:28 millert Exp $ */
+/* $OpenBSD: main.c,v 1.13 2004/12/30 01:52:48 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -23,7 +23,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
-const char *version = "version 20021213";
+const char *version = "version 20041222";
#define DEBUG
#include <stdio.h>
@@ -60,7 +60,7 @@ int main(int argc, char *argv[])
const char *fs = NULL;
setlocale(LC_ALL, "");
-
+ setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
cmdname = __progname;
if (argc == 1) {
fprintf(stderr, "usage: %s [-F fs] [-v var=value] [-safe] "
@@ -153,6 +153,7 @@ int main(int argc, char *argv[])
if (!safe)
envinit(environ);
yyparse();
+ setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
if (fs)
*FS = qstring(fs, '\0');
dprintf( ("errorflag=%d\n", errorflag) );
diff --git a/usr.bin/awk/run.c b/usr.bin/awk/run.c
index 169f7e8e0d8..0196f2c66f4 100644
--- a/usr.bin/awk/run.c
+++ b/usr.bin/awk/run.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: run.c,v 1.24 2004/05/08 22:08:51 millert Exp $ */
+/* $OpenBSD: run.c,v 1.25 2004/12/30 01:52:48 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -27,6 +27,7 @@ THIS SOFTWARE.
#include <stdio.h>
#include <ctype.h>
#include <setjmp.h>
+#include <limits.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
@@ -225,6 +226,7 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
{
static Cell newcopycell = { OCELL, CCOPY, 0, "", 0.0, NUM|STR|DONTFREE };
int i, ncall, ndef;
+ int freed = 0; /* handles potential double freeing when fcn & param share a tempcell */
Node *x;
Cell *args[NARGS], *oargs[NARGS]; /* BUG: fixed size arrays */
Cell *y, *z, *fcn;
@@ -302,12 +304,18 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
} else if (t != y) { /* kludge to prevent freeing twice */
t->csub = CTEMP;
tempfree(t);
+ } else if (t == y && t->csub == CCOPY) {
+ t->csub = CTEMP;
+ tempfree(t);
+ freed = 1;
}
}
tempfree(fcn);
if (isexit(y) || isnext(y))
return y;
- tempfree(y); /* this can free twice! */
+ if (freed == 0) {
+ tempfree(y); /* don't free twice! */
+ }
z = fp->retval; /* return value */
dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) );
fp--;
@@ -704,12 +712,16 @@ Cell *gettemp(void) /* get a tempcell */
Cell *indirect(Node **a, int n) /* $( a[0] ) */
{
+ Awkfloat val;
Cell *x;
int m;
char *s;
x = execute(a[0]);
- m = (int) getfval(x);
+ val = getfval(x); /* freebsd: defend against super large field numbers */
+ if ((Awkfloat)INT_MAX < val)
+ FATAL("trying to access out of range field %s", x->nval);
+ m = (int) val;
if (m == 0 && !is_number(s = getsval(x))) /* suspicion! */
FATAL("illegal field $(%s), name \"%s\"", s, x->nval);
/* BUG: can x->nval ever be null??? */
@@ -1230,7 +1242,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
ap->sval = (char *) makesymtab(NSYMTAB);
n = 0;
- if ((*s != '\0' && strlen(fs) > 1) || arg3type == REGEXPR) { /* reg expr */
+ if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */
fa *pfa;
if (arg3type == REGEXPR) { /* it's ready already */
pfa = (fa *) a[2];
@@ -1259,6 +1271,8 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
goto spdone;
}
} while (nematch(pfa,s));
+ pfa->initstat = tempstat; /* bwk: has to be here to reset */
+ /* cf gsub and refldbld */
}
n++;
snprintf(num, sizeof num, "%d", n);
@@ -1522,11 +1536,11 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
if (t == FTOUPPER) {
for (p = buf; *p; p++)
if (islower((uschar) *p))
- *p = toupper(*p);
+ *p = toupper((uschar)*p);
} else {
for (p = buf; *p; p++)
if (isupper((uschar) *p))
- *p = tolower(*p);
+ *p = tolower((uschar)*p);
}
tempfree(x);
x = gettemp();
diff --git a/usr.bin/awk/tran.c b/usr.bin/awk/tran.c
index 170fe76d0fa..691b411f6b8 100644
--- a/usr.bin/awk/tran.c
+++ b/usr.bin/awk/tran.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tran.c,v 1.10 2003/04/06 06:12:01 pvalchev Exp $ */
+/* $OpenBSD: tran.c,v 1.11 2004/12/30 01:52:48 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -52,6 +52,7 @@ char **SUBSEP; /* subscript separator for a[i,j,k]; default \034 */
Awkfloat *RSTART; /* start of re matched with ~; origin 1 (!) */
Awkfloat *RLENGTH; /* length of same */
+Cell *fsloc; /* FS */
Cell *nrloc; /* NR */
Cell *nfloc; /* NF */
Cell *fnrloc; /* FNR */
@@ -74,7 +75,8 @@ void syminit(void) /* initialize symbol table with builtin vars */
nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON|DONTFREE, symtab);
nullnode = celltonode(nullloc, CCON);
- FS = &setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab)->sval;
+ 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;
@@ -316,7 +318,8 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
char *t;
int fldno;
- dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, NN(vp->nval), s, vp->tval) );
+ dprintf( ("starting setsval %p: %s = \"%s\", t=%o, r,f=%d,%d\n",
+ vp, NN(vp->nval), s, vp->tval, donerec, donefld) );
if ((vp->tval & (NUM | STR)) == 0)
funnyvar(vp, "assign to");
if (isfld(vp)) {
@@ -335,7 +338,8 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
if (freeable(vp))
xfree(vp->sval);
vp->tval &= ~DONTFREE;
- dprintf( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, NN(vp->nval), t,t, vp->tval) );
+ dprintf( ("setsval %p: %s = \"%s (%p) \", t=%o r,f=%d,%d\n",
+ vp, NN(vp->nval), t,t, vp->tval, donerec, donefld) );
return(vp->sval = t);
}
@@ -356,8 +360,7 @@ Awkfloat getfval(Cell *vp) /* get float val of a Cell */
return(vp->fval);
}
- static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
-
+static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
{
char s[100]; /* BUG: unchecked */
double dtemp;