=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/awk/b.c,v retrieving revision 1.26 retrieving revision 1.27 diff -c -r1.26 -r1.27 *** src/usr.bin/awk/b.c 2020/06/10 21:02:53 1.26 --- src/usr.bin/awk/b.c 2020/06/10 21:03:12 1.27 *************** *** 1,4 **** ! /* $OpenBSD: b.c,v 1.26 2020/06/10 21:02:53 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved --- 1,4 ---- ! /* $OpenBSD: b.c,v 1.27 2020/06/10 21:03:12 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved *************** *** 77,86 **** char *patbeg; int patlen; ! #define NFA 20 /* cache this many dynamic fa's */ fa *fatab[NFA]; int nfatab = 0; /* entries in fatab */ fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */ { int i, use, nuse; --- 77,154 ---- char *patbeg; int patlen; ! #define NFA 128 /* cache this many dynamic fa's */ fa *fatab[NFA]; int nfatab = 0; /* entries in fatab */ + static int * + intalloc(size_t n, const char *f) + { + void *p = calloc(n, sizeof(int)); + if (p == NULL) + overflo(f); + return p; + } + + static void + allocsetvec(const char *f) + { + maxsetvec = MAXLIN; + setvec = reallocarray(setvec, maxsetvec, sizeof(*setvec)); + tmpset = reallocarray(tmpset, maxsetvec, sizeof(*tmpset)); + if (setvec == NULL || tmpset == NULL) + overflo(f); + } + + static void + resizesetvec(const char *f) + { + setvec = reallocarray(setvec, maxsetvec, 4 * sizeof(*setvec)); + tmpset = reallocarray(tmpset, maxsetvec, 4 * sizeof(*tmpset)); + if (setvec == NULL || tmpset == NULL) + overflo(f); + maxsetvec *= 4; + } + + static void + resize_state(fa *f, int state) + { + void *p; + int i, new_count; + + if (++state < f->state_count) + return; + + new_count = state + 10; /* needs to be tuned */ + + p = reallocarray(f->gototab, new_count, sizeof(f->gototab[0])); + if (p == NULL) + goto out; + f->gototab = p; + + p = reallocarray(f->out, new_count, sizeof(f->out[0])); + if (p == NULL) + goto out; + f->out = p; + + p = reallocarray(f->posns, new_count, sizeof(f->posns[0])); + if (p == NULL) + goto out; + f->posns = p; + + for (i = f->state_count; i < new_count; ++i) { + f->gototab[i] = calloc(NCHARS, sizeof(**f->gototab)); + if (f->gototab[i] == NULL) + goto out; + f->out[i] = 0; + f->posns[i] = NULL; + } + f->state_count = new_count; + return; + out: + overflo(__func__); + } + fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */ { int i, use, nuse; *************** *** 88,98 **** static int now = 1; if (setvec == NULL) { /* first time through any RE */ ! maxsetvec = MAXLIN; ! setvec = (int *) calloc(maxsetvec, sizeof(int)); ! tmpset = (int *) calloc(maxsetvec, sizeof(int)); ! if (setvec == NULL || tmpset == NULL) ! overflo("out of space initializing makedfa"); } if (compile_time) /* a constant for sure */ --- 156,162 ---- static int now = 1; if (setvec == NULL) { /* first time through any RE */ ! allocsetvec(__func__); } if (compile_time) /* a constant for sure */ *************** *** 140,153 **** poscnt = 0; penter(p1); /* enter parent pointers and leaf indices */ if ((f = (fa *) calloc(1, sizeof(fa) + poscnt*sizeof(rrow))) == NULL) ! overflo("out of space for fa"); f->accept = poscnt-1; /* penter has computed number of positions in re */ cfoll(f, p1); /* set up follow sets */ freetr(p1); ! if ((f->posns[0] = (int *) calloc(*(f->re[0].lfollow), sizeof(int))) == NULL) ! overflo("out of space in makedfa"); ! if ((f->posns[1] = (int *) calloc(1, sizeof(int))) == NULL) ! overflo("out of space in makedfa"); *f->posns[1] = 0; f->initstat = makeinit(f, anchor); f->anchor = anchor; --- 204,216 ---- poscnt = 0; penter(p1); /* enter parent pointers and leaf indices */ if ((f = (fa *) calloc(1, sizeof(fa) + poscnt*sizeof(rrow))) == NULL) ! overflo(__func__); f->accept = poscnt-1; /* penter has computed number of positions in re */ cfoll(f, p1); /* set up follow sets */ freetr(p1); ! resize_state(f, 1); ! f->posns[0] = intalloc(*(f->re[0].lfollow), __func__); ! f->posns[1] = intalloc(1, __func__); *f->posns[1] = 0; f->initstat = makeinit(f, anchor); f->anchor = anchor; *************** *** 165,175 **** f->curstat = 2; f->out[2] = 0; - f->reset = 0; k = *(f->re[0].lfollow); xfree(f->posns[2]); ! if ((f->posns[2] = (int *) calloc(k+1, sizeof(int))) == NULL) ! overflo("out of space in makeinit"); for (i=0; i <= k; i++) { (f->posns[2])[i] = (f->re[0].lfollow)[i]; } --- 228,236 ---- f->curstat = 2; f->out[2] = 0; k = *(f->re[0].lfollow); xfree(f->posns[2]); ! f->posns[2] = intalloc(k + 1, __func__); for (i=0; i <= k; i++) { (f->posns[2])[i] = (f->re[0].lfollow)[i]; } *************** *** 309,315 **** static int bufsz = 100; op = p; ! if (buf == NULL && (buf = (uschar *) malloc(bufsz)) == NULL) FATAL("out of space for character class [%.10s...] 1", p); bp = buf; for (i = 0; (c = *p++) != 0; ) { --- 370,376 ---- static int bufsz = 100; op = p; ! if (buf == NULL && (buf = malloc(bufsz)) == NULL) FATAL("out of space for character class [%.10s...] 1", p); bp = buf; for (i = 0; (c = *p++) != 0; ) { *************** *** 348,354 **** void overflo(const char *s) { ! FATAL("regular expression too big: %.30s...", s); } void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfollow[leaf] */ --- 409,415 ---- void overflo(const char *s) { ! FATAL("regular expression too big: out of space in %.30s...", s); } void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfollow[leaf] */ *************** *** 362,381 **** f->re[info(v)].ltype = type(v); f->re[info(v)].lval.np = right(v); while (f->accept >= maxsetvec) { /* guessing here! */ ! setvec = reallocarray(setvec, maxsetvec, ! 4 * sizeof(int)); ! tmpset = reallocarray(tmpset, maxsetvec, ! 4 * sizeof(int)); ! if (setvec == NULL || tmpset == NULL) ! overflo("out of space in cfoll()"); ! maxsetvec *= 4; } for (i = 0; i <= f->accept; i++) setvec[i] = 0; setcnt = 0; follow(v); /* computes setvec and setcnt */ ! if ((p = (int *) calloc(setcnt+1, sizeof(int))) == NULL) ! overflo("out of space building follow set"); f->re[info(v)].lfollow = p; *p = setcnt; for (i = f->accept; i >= 0; i--) --- 423,435 ---- f->re[info(v)].ltype = type(v); f->re[info(v)].lval.np = right(v); while (f->accept >= maxsetvec) { /* guessing here! */ ! resizesetvec(__func__); } for (i = 0; i <= f->accept; i++) setvec[i] = 0; setcnt = 0; follow(v); /* computes setvec and setcnt */ ! p = intalloc(setcnt + 1, __func__); f->re[info(v)].lfollow = p; *p = setcnt; for (i = f->accept; i >= 0; i--) *************** *** 405,417 **** LEAF lp = info(p); /* look for high-water mark of subscripts */ while (setcnt >= maxsetvec || lp >= maxsetvec) { /* guessing here! */ ! setvec = reallocarray(setvec, maxsetvec, ! 4 * sizeof(int)); ! tmpset = reallocarray(tmpset, maxsetvec, ! 4 * sizeof(int)); ! if (setvec == NULL || tmpset == NULL) ! overflo("out of space in first()"); ! maxsetvec *= 4; } if (type(p) == EMPTYRE) { setvec[lp] = 0; --- 459,465 ---- LEAF lp = info(p); /* look for high-water mark of subscripts */ while (setcnt >= maxsetvec || lp >= maxsetvec) { /* guessing here! */ ! resizesetvec(__func__); } if (type(p) == EMPTYRE) { setvec[lp] = 0; *************** *** 489,495 **** int s, ns; uschar *p = (uschar *) p0; ! s = f->reset ? makeinit(f,0) : f->initstat; if (f->out[s]) return(1); do { --- 537,545 ---- int s, ns; uschar *p = (uschar *) p0; ! s = f->initstat; ! assert (s < f->state_count); ! if (f->out[s]) return(1); do { *************** *** 509,523 **** int s, ns; uschar *p = (uschar *) p0; uschar *q; - int i, k; ! /* 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 { q = p; --- 559,569 ---- int s, ns; uschar *p = (uschar *) p0; uschar *q; ! s = f->initstat; ! assert(s < f->state_count); ! ! patbeg = (char *)p; patlen = -1; do { q = p; *************** *** 529,534 **** --- 575,583 ---- s = ns; else s = cgoto(f, s, *q); + + assert(s < f->state_count); + if (s == 1) { /* no transition */ if (patlen >= 0) { patbeg = (char *) p; *************** *** 546,565 **** } nextin: s = 2; ! if (f->reset) { ! for (i = 2; i <= f->curstat; i++) ! xfree(f->posns[i]); ! k = *f->posns[0]; ! if ((f->posns[2] = (int *) calloc(k+1, sizeof(int))) == NULL) ! overflo("out of space in pmatch"); ! for (i = 0; i <= k; i++) ! (f->posns[2])[i] = (f->posns[0])[i]; ! f->initstat = f->curstat = 2; ! f->out[2] = f->out[0]; ! for (i = 0; i < NCHARS; i++) ! f->gototab[2][i] = 0; ! } ! } while (*p++ != 0); return (0); } --- 595,601 ---- } nextin: s = 2; ! } while (*p++); return (0); } *************** *** 568,581 **** int s, ns; uschar *p = (uschar *) p0; uschar *q; - int i, k; ! /* 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; --- 604,614 ---- int s, ns; uschar *p = (uschar *) p0; uschar *q; ! s = f->initstat; ! assert(s < f->state_count); ! ! patbeg = (char *)p; patlen = -1; while (*p) { q = p; *************** *** 603,621 **** } nnextin: s = 2; - if (f->reset) { - for (i = 2; i <= f->curstat; i++) - xfree(f->posns[i]); - k = *f->posns[0]; - if ((f->posns[2] = (int *) calloc(k+1, sizeof(int))) == NULL) - overflo("out of state space"); - for (i = 0; i <= k; i++) - (f->posns[2])[i] = (f->posns[0])[i]; - f->initstat = f->curstat = 2; - f->out[2] = f->out[0]; - for (i = 0; i < NCHARS; i++) - f->gototab[2][i] = 0; - } p++; } return (0); --- 636,641 ---- *************** *** 913,919 **** } else if (special_case == REPEAT_ZERO) { size += 2; /* just a null ERE: () */ } ! if ((buf = (uschar *) malloc(size+1)) == NULL) FATAL("out of space in reg expr %.10s..", lastre); memcpy(buf, basestr, prefix_length); /* copy prefix */ j = prefix_length; --- 933,939 ---- } else if (special_case == REPEAT_ZERO) { size += 2; /* just a null ERE: () */ } ! if ((buf = malloc(size + 1)) == NULL) FATAL("out of space in reg expr %.10s..", lastre); memcpy(buf, basestr, prefix_length); /* copy prefix */ j = prefix_length; *************** *** 1039,1045 **** rlxval = c; return CHAR; case '[': ! if (buf == NULL && (buf = (uschar *) malloc(bufsz)) == NULL) FATAL("out of space in reg expr %.10s..", lastre); bp = buf; if (*prestr == '^') { --- 1059,1065 ---- rlxval = c; return CHAR; case '[': ! if (buf == NULL && (buf = malloc(bufsz)) == NULL) FATAL("out of space in reg expr %.10s..", lastre); bp = buf; if (*prestr == '^') { *************** *** 1207,1226 **** int cgoto(fa *f, int s, int c) { - int i, j, k; int *p, *q; assert(c == HAT || c < NCHARS); while (f->accept >= maxsetvec) { /* guessing here! */ ! setvec = reallocarray(setvec, maxsetvec, 4 * sizeof(int)); ! tmpset = reallocarray(tmpset, maxsetvec, 4 * sizeof(int)); ! if (setvec == NULL || tmpset == NULL) ! overflo("out of space in cgoto()"); ! maxsetvec *= 4; } for (i = 0; i <= f->accept; i++) setvec[i] = 0; setcnt = 0; /* compute positions of gototab[s,c] into setvec */ p = f->posns[s]; for (i = 1; i <= *p; i++) { --- 1227,1243 ---- int cgoto(fa *f, int s, int c) { int *p, *q; + int i, j, k; assert(c == HAT || c < NCHARS); while (f->accept >= maxsetvec) { /* guessing here! */ ! resizesetvec(__func__); } for (i = 0; i <= f->accept; i++) setvec[i] = 0; setcnt = 0; + resize_state(f, s); /* compute positions of gototab[s,c] into setvec */ p = f->posns[s]; for (i = 1; i <= *p; i++) { *************** *** 1234,1246 **** q = f->re[p[i]].lfollow; for (j = 1; j <= *q; j++) { if (q[j] >= maxsetvec) { ! setvec = reallocarray(setvec, ! maxsetvec, 4 * sizeof(int)); ! tmpset = reallocarray(tmpset, ! maxsetvec, 4 * sizeof(int)); ! if (setvec == 0 || tmpset == 0) ! overflo("cgoto overflow"); ! maxsetvec *= 4; } if (setvec[q[j]] == 0) { setcnt++; --- 1251,1257 ---- q = f->re[p[i]].lfollow; for (j = 1; j <= *q; j++) { if (q[j] >= maxsetvec) { ! resizesetvec(__func__); } if (setvec[q[j]] == 0) { setcnt++; *************** *** 1257,1262 **** --- 1268,1274 ---- if (setvec[i]) { tmpset[j++] = i; } + resize_state(f, f->curstat > s ? f->curstat : s); /* tmpset == previous state? */ for (i = 1; i <= f->curstat; i++) { p = f->posns[i]; *************** *** 1272,1289 **** } /* add tmpset to current set of states */ ! if (f->curstat >= NSTATES-1) { ! f->curstat = 2; ! f->reset = 1; ! for (i = 2; i < NSTATES; i++) ! xfree(f->posns[i]); ! } else ! ++(f->curstat); for (i = 0; i < NCHARS; i++) f->gototab[f->curstat][i] = 0; xfree(f->posns[f->curstat]); ! if ((p = (int *) calloc(setcnt+1, sizeof(int))) == NULL) ! overflo("out of space in cgoto"); f->posns[f->curstat] = p; f->gototab[s][c] = f->curstat; --- 1284,1295 ---- } /* add tmpset to current set of states */ ! ++(f->curstat); ! resize_state(f, f->curstat); for (i = 0; i < NCHARS; i++) f->gototab[f->curstat][i] = 0; xfree(f->posns[f->curstat]); ! p = intalloc(setcnt + 1, __func__); f->posns[f->curstat] = p; f->gototab[s][c] = f->curstat; *************** *** 1303,1308 **** --- 1309,1316 ---- if (f == NULL) return; + for (i = 0; i < f->state_count; i++) + xfree(f->gototab[i]) for (i = 0; i <= f->curstat; i++) xfree(f->posns[i]); for (i = 0; i <= f->accept; i++) { *************** *** 1311,1315 **** --- 1319,1326 ---- xfree((f->re[i].lval.np)); } xfree(f->restr); + xfree(f->out); + xfree(f->posns); + xfree(f->gototab); xfree(f); }