diff -urBw nvi-1.81.6.orig/common/key.c nvi-1.81.6/common/key.c --- nvi-1.81.6.orig/common/key.c 2007-11-19 01:41:42.000000000 +0900 +++ nvi-1.81.6/common/key.c 2008-09-01 06:00:31.000000000 +0900 @@ -626,7 +626,8 @@ */ if (istimeout || FL_ISSET(evp->e_flags, CH_NOMAP) || !LF_ISSET(EC_MAPCOMMAND | EC_MAPINPUT) || - evp->e_c < MAX_BIT_SEQ && !bit_test(gp->seqb, evp->e_c)) + (UCHAR_T)evp->e_c < MAX_BIT_SEQ && + !bit_test(gp->seqb, (UCHAR_T)evp->e_c)) goto nomap; /* Search the map. */ diff -urBw nvi-1.81.6.orig/common/multibyte.h nvi-1.81.6/common/multibyte.h --- nvi-1.81.6.orig/common/multibyte.h 2007-11-19 01:41:42.000000000 +0900 +++ nvi-1.81.6/common/multibyte.h 2008-09-01 05:57:19.000000000 +0900 @@ -6,11 +6,11 @@ #include typedef wchar_t RCHAR_T; -#define RCHAR_T_MAX ((1 << 24)-1) +#define RCHAR_T_MAX 0xffffffff typedef wchar_t CHAR_T; -#define MAX_CHAR_T 0xffffff /* XXXX */ +#define MAX_CHAR_T 0xffffffff typedef u_int UCHAR_T; -#define RCHAR_BIT 24 +#define RCHAR_BIT 32 #define STRLEN wcslen #define STRTOL wcstol diff -urBw nvi-1.81.6.orig/regex/engine.c nvi-1.81.6/regex/engine.c --- nvi-1.81.6.orig/regex/engine.c 2007-11-19 01:41:42.000000000 +0900 +++ nvi-1.81.6/regex/engine.c 2008-09-01 05:57:20.000000000 +0900 @@ -328,20 +328,20 @@ for (ss = startst; ss < stopst; ss = es) { /* identify end of subRE */ es = ss; - switch (OP(m->g->strip[es])) { + switch (m->g->strip[es]) { case OPLUS_: case OQUEST_: - es += OPND(m->g->strip[es]); + es += m->g->stripdata[es]; break; case OCH_: - while (OP(m->g->strip[es]) != O_CH) - es += OPND(m->g->strip[es]); + while (m->g->strip[es] != O_CH) + es += m->g->stripdata[es]; break; } es++; /* figure out what it matched */ - switch (OP(m->g->strip[ss])) { + switch (m->g->strip[ss]) { case OEND: assert(nope); break; @@ -437,21 +437,21 @@ assert(stp >= sp); /* it did work */ } ssub = ss + 1; - esub = ss + OPND(m->g->strip[ss]) - 1; - assert(OP(m->g->strip[esub]) == OOR1); + esub = ss + m->g->stripdata[ss] - 1; + assert(m->g->strip[esub] == OOR1); for (;;) { /* find first matching branch */ if (slow(m, sp, rest, ssub, esub) == rest) break; /* it matched all of it */ /* that one missed, try next one */ - assert(OP(m->g->strip[esub]) == OOR1); + assert(m->g->strip[esub] == OOR1); esub++; - assert(OP(m->g->strip[esub]) == OOR2); + assert(m->g->strip[esub] == OOR2); ssub = esub + 1; - esub += OPND(m->g->strip[esub]); - if (OP(m->g->strip[esub]) == OOR2) + esub += m->g->stripdata[esub]; + if (m->g->strip[esub] == OOR2) esub--; else - assert(OP(m->g->strip[esub]) == O_CH); + assert(m->g->strip[esub] == O_CH); } dp = dissect(m, sp, rest, ssub, esub); assert(dp == rest); @@ -465,12 +465,12 @@ assert(nope); break; case OLPAREN: - i = OPND(m->g->strip[ss]); + i = m->g->stripdata[ss]; assert(0 < i && i <= m->g->nsub); m->pmatch[i].rm_so = sp - m->offp; break; case ORPAREN: - i = OPND(m->g->strip[ss]); + i = m->g->stripdata[ss]; assert(0 < i && i <= m->g->nsub); m->pmatch[i].rm_eo = sp - m->offp; break; @@ -508,6 +508,7 @@ register size_t len; register int hard; register sop s; + register RCHAR_T d; register regoff_t offsave; register cset *cs; @@ -517,9 +518,11 @@ /* get as far as we can with easy stuff */ hard = 0; for (ss = startst; !hard && ss < stopst; ss++) - switch (OP(s = m->g->strip[ss])) { + s = m->g->strip[ss]; + d = m->g->stripdata[ss]; + switch (s) { case OCHAR: - if (sp == stop || *sp++ != (RCHAR_T)OPND(s)) + if (sp == stop || *sp++ != d) return(NULL); break; case OANY: @@ -528,7 +531,7 @@ sp++; break; case OANYOF: - cs = &m->g->sets[OPND(s)]; + cs = &m->g->sets[d]; if (sp == stop || !CHIN(cs, *sp++)) return(NULL); break; @@ -575,9 +578,10 @@ ss++; s = m->g->strip[ss]; do { - assert(OP(s) == OOR2); - ss += OPND(s); - } while (OP(s = m->g->strip[ss]) != O_CH); + assert(s == OOR2); + d = m->g->stripdata[ss]; + ss += d; + } while ((s = m->g->strip[ss]) != O_CH); /* note that the ss++ gets us past the O_CH */ break; default: /* have to make a choice */ @@ -594,9 +598,10 @@ /* the hard stuff */ AT("hard", sp, stop, ss, stopst); s = m->g->strip[ss]; - switch (OP(s)) { + d = m->g->stripdata[ss]; + switch (s) { case OBACK_: /* the vilest depths */ - i = OPND(s); + i = d; assert(0 < i && i <= m->g->nsub); if (m->pmatch[i].rm_eo == -1) return(NULL); @@ -608,7 +613,7 @@ ssp = m->offp + m->pmatch[i].rm_so; if (memcmp(sp, ssp, len) != 0) return(NULL); - while (m->g->strip[ss] != SOP(O_BACK, i)) + while (m->g->strip[ss] != O_BACK || m->g->stripdata[ss] != i) ss++; return(backref(m, sp+len, stop, ss+1, stopst, lev)); break; @@ -616,7 +621,7 @@ dp = backref(m, sp, stop, ss+1, stopst, lev); if (dp != NULL) return(dp); /* not */ - return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev)); + return(backref(m, sp, stop, ss+d+1, stopst, lev)); break; case OPLUS_: assert(m->lastpos != NULL); @@ -629,7 +634,7 @@ return(backref(m, sp, stop, ss+1, stopst, lev-1)); /* try another pass */ m->lastpos[lev] = sp; - dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev); + dp = backref(m, sp, stop, ss-d+1, stopst, lev); if (dp == NULL) return(backref(m, sp, stop, ss+1, stopst, lev-1)); else @@ -637,27 +642,27 @@ break; case OCH_: /* find the right one, if any */ ssub = ss + 1; - esub = ss + OPND(s) - 1; - assert(OP(m->g->strip[esub]) == OOR1); + esub = ss + d - 1; + assert(m->g->strip[esub] == OOR1); for (;;) { /* find first matching branch */ dp = backref(m, sp, stop, ssub, esub, lev); if (dp != NULL) return(dp); /* that one missed, try next one */ - if (OP(m->g->strip[esub]) == O_CH) + if (m->g->strip[esub] == O_CH) return(NULL); /* there is none */ esub++; - assert(OP(m->g->strip[esub]) == OOR2); + assert(m->g->strip[esub] == OOR2); ssub = esub + 1; - esub += OPND(m->g->strip[esub]); - if (OP(m->g->strip[esub]) == OOR2) + esub += m->g->stripdata[esub]; + if (m->g->strip[esub] == OOR2) esub--; else - assert(OP(m->g->strip[esub]) == O_CH); + assert(m->g->strip[esub] == O_CH); } break; case OLPAREN: /* must undo assignment if rest fails */ - i = OPND(s); + i = d; assert(0 < i && i <= m->g->nsub); offsave = m->pmatch[i].rm_so; m->pmatch[i].rm_so = sp - m->offp; @@ -668,7 +673,7 @@ return(NULL); break; case ORPAREN: /* must undo assignment if rest fails */ - i = OPND(s); + i = d; assert(0 < i && i <= m->g->nsub); offsave = m->pmatch[i].rm_eo; m->pmatch[i].rm_eo = sp - m->offp; @@ -891,6 +896,7 @@ { register cset *cs; register sop s; + register RCHAR_T d; register sopno pc; register onestate here; /* note, macros know this name */ register sopno look; @@ -898,14 +904,15 @@ for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { s = g->strip[pc]; - switch (OP(s)) { + d = g->stripdata[pc]; + switch (s) { case OEND: assert(pc == stop-1); break; case OCHAR: /* only characters can match */ - assert(!NONCHAR(ch) || ch != (RCHAR_T)OPND(s)); - if (ch == (RCHAR_T)OPND(s)) + assert(!NONCHAR(ch) || ch != d); + if (ch == d) FWD(aft, bef, 1); break; case OBOL: @@ -929,7 +936,7 @@ FWD(aft, bef, 1); break; case OANYOF: - cs = &g->sets[OPND(s)]; + cs = &g->sets[d]; if (!NONCHAR(ch) && CHIN(cs, ch)) FWD(aft, bef, 1); break; @@ -942,17 +949,17 @@ break; case O_PLUS: /* both forward and back */ FWD(aft, aft, 1); - i = ISSETBACK(aft, OPND(s)); - BACK(aft, aft, OPND(s)); - if (!i && ISSETBACK(aft, OPND(s))) { + i = ISSETBACK(aft, d); + BACK(aft, aft, d); + if (!i && ISSETBACK(aft, d)) { /* oho, must reconsider loop body */ - pc -= OPND(s) + 1; + pc -= d + 1; INIT(here, pc); } break; case OQUEST_: /* two branches, both forward */ FWD(aft, aft, 1); - FWD(aft, aft, OPND(s)); + FWD(aft, aft, d); break; case O_QUEST: /* just an empty */ FWD(aft, aft, 1); @@ -963,23 +970,27 @@ break; case OCH_: /* mark the first two branches */ FWD(aft, aft, 1); - assert(OP(g->strip[pc+OPND(s)]) == OOR2); - FWD(aft, aft, OPND(s)); + assert(g->strip[pc+d] == OOR2); + FWD(aft, aft, d); break; case OOR1: /* done a branch, find the O_CH */ if (ISSTATEIN(aft, here)) { - for (look = 1; - OP(s = g->strip[pc+look]) != O_CH; - look += OPND(s)) - assert(OP(s) == OOR2); + for (look = 1;;) { + s = g->strip[pc+look]; + d = g->stripdata[pc+look]; + if (s == O_CH) + break; + assert(s == OOR2); + look += d; + } FWD(aft, aft, look); } break; case OOR2: /* propagate OCH_'s marking */ FWD(aft, aft, 1); - if (OP(g->strip[pc+OPND(s)]) != O_CH) { - assert(OP(g->strip[pc+OPND(s)]) == OOR2); - FWD(aft, aft, OPND(s)); + if (g->strip[pc+d] != O_CH) { + assert(g->strip[pc+d] == OOR2); + FWD(aft, aft, d); } break; case O_CH: /* just empty */ diff -urBw nvi-1.81.6.orig/regex/regcomp.c nvi-1.81.6/regex/regcomp.c --- nvi-1.81.6.orig/regex/regcomp.c 2007-11-19 01:41:42.000000000 +0900 +++ nvi-1.81.6/regex/regcomp.c 2008-09-01 05:57:20.000000000 +0900 @@ -64,6 +64,7 @@ RCHAR_T *end; /* end of string (-> NUL normally) */ int error; /* has an error been seen? */ sop *strip; /* malloced strip */ + RCHAR_T *stripdata; /* malloced stripdata */ sopno ssize; /* malloced strip size (allocated) */ sopno slen; /* malloced strip length (used) */ int ncsalloc; /* number of csets allocated */ @@ -207,11 +208,17 @@ return(REG_ESPACE); p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ p->strip = (sop *)malloc(p->ssize * sizeof(sop)); - p->slen = 0; if (p->strip == NULL) { free((char *)g); return(REG_ESPACE); } + p->stripdata = (RCHAR_T *)malloc(p->ssize * sizeof(RCHAR_T)); + if (p->stripdata == NULL) { + free((char *)p->strip); + free((char *)g); + return(REG_ESPACE); + } + p->slen = 0; /* set things up */ p->g = g; @@ -530,13 +537,13 @@ /* is a leading * an ordinary character? */ { - register int c; + register unsigned long long c; /* XXX: FIXME */ register int count; register int count2; register sopno pos; register int i; register sopno subno; -# define BACKSL (1<g->nsub); EMIT(OBACK_, i); assert(p->pbegin[i] != 0); - assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); - assert(OP(p->strip[p->pend[i]]) == ORPAREN); + assert(p->strip[p->pbegin[i]] == OLPAREN); + assert(p->strip[p->pend[i]] == ORPAREN); (void) dupl(p, p->pbegin[i]+1, p->pend[i]); EMIT(O_BACK, i); } else @@ -1403,6 +1410,8 @@ assert(p->ssize >= p->slen + len); (void) memcpy((char *)(p->strip + p->slen), (char *)(p->strip + start), (size_t)len*sizeof(sop)); + (void) memcpy((char *)(p->stripdata + p->slen), + (char *)(p->stripdata + start), (size_t)len*sizeof(RCHAR_T)); p->slen += len; return(ret); } @@ -1423,7 +1432,7 @@ return; /* deal with oversize operands ("can't happen", more or less) */ - assert(opnd < 1<slen >= p->ssize) @@ -1431,7 +1440,9 @@ assert(p->slen < p->ssize); /* finally, it's all reduced to the easy case */ - p->strip[p->slen++] = SOP(op, opnd); + p->strip[p->slen] = op; + p->stripdata[p->slen] = opnd; + ++p->slen; } /* @@ -1443,6 +1454,7 @@ { register sopno sn; register sop s; + register RCHAR_T d; register int i; /* avoid making error situations worse */ @@ -1453,6 +1465,7 @@ EMIT(op, opnd); /* do checks, ensure space */ assert(HERE() == sn+1); s = p->strip[sn]; + d = p->stripdata[sn]; /* adjust paren pointers */ assert(pos > 0); @@ -1467,7 +1480,10 @@ memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], (HERE()-pos-1)*sizeof(sop)); + memmove((char *)&p->stripdata[pos+1], (char *)&p->stripdata[pos], + (HERE()-pos-1)*sizeof(RCHAR_T)); p->strip[pos] = s; + p->stripdata[pos] = d; } /* @@ -1481,8 +1497,8 @@ if (p->error != 0) return; - assert(value < 1<strip[pos] = OP(p->strip[pos]) | value; + assert(value < 1); + p->stripdata[pos] = value; } /* @@ -1493,6 +1509,7 @@ enlarge(register struct parse *p, register sopno size) { register sop *sp; + register RCHAR_T *dp; if (p->ssize >= size) return; @@ -1503,6 +1520,12 @@ return; } p->strip = sp; + dp = (RCHAR_T *)realloc(p->stripdata, size*sizeof(RCHAR_T *)); + if (dp == NULL) { + SETERROR(REG_ESPACE); + return; + } + p->stripdata = dp; p->ssize = size; } @@ -1519,6 +1542,12 @@ SETERROR(REG_ESPACE); g->strip = p->strip; } + g->stripdata = (RCHAR_T *)realloc((char *)p->stripdata, + p->slen * sizeof(RCHAR_T)); + if (g->stripdata == NULL) { + SETERROR(REG_ESPACE); + g->stripdata = p->stripdata; + } } /* @@ -1534,11 +1563,15 @@ static void findmust(struct parse *p, register struct re_guts *g) { - register sop *scan; - sop *start; - register sop *newstart; + register sop *scans; + register RCHAR_T *scand; + sop *starts; + RCHAR_T *startd; + register sop *newstarts; + register RCHAR_T *newstartd; register sopno newlen; register sop s; + register RCHAR_T d; register RCHAR_T *cp; register sopno i; @@ -1548,13 +1581,17 @@ /* find the longest OCHAR sequence in strip */ newlen = 0; - scan = g->strip + 1; + scans = g->strip + 1; + scand = g->stripdata + 1; do { - s = *scan++; - switch (OP(s)) { + s = *scans++; + d = *scand++; + switch (s) { case OCHAR: /* sequence member */ - if (newlen == 0) /* new sequence */ - newstart = scan - 1; + if (newlen == 0) { /* new sequence */ + newstarts = scans - 1; + newstartd = scand - 1; + } newlen++; break; case OPLUS_: /* things that don't break one */ @@ -1563,27 +1600,30 @@ break; case OQUEST_: /* things that must be skipped */ case OCH_: - scan--; + scans--; + scand--; do { - scan += OPND(s); - s = *scan; + scans += d; + scand += d; + s = *scans; + d = *scand; /* assert() interferes w debug printouts */ - if (OP(s) != O_QUEST && OP(s) != O_CH && - OP(s) != OOR2) { + if (s != O_QUEST && s != O_CH && s != OOR2) { g->iflags |= BAD; return; } - } while (OP(s) != O_QUEST && OP(s) != O_CH); + } while (s != O_QUEST && s != O_CH); /* fallthrough */ default: /* things that break a sequence */ if (newlen > g->mlen) { /* ends one */ - start = newstart; + starts = newstarts; + startd = newstartd; g->mlen = newlen; } newlen = 0; break; } - } while (OP(s) != OEND); + } while (s != OEND); if (g->mlen == 0) /* there isn't one */ return; @@ -1595,12 +1635,17 @@ return; } cp = g->must; - scan = start; + scans = starts; + scand = startd; for (i = g->mlen; i > 0; i--) { - while (OP(s = *scan++) != OCHAR) - continue; + for (;;) { + s = *scans++; + d = *scand++; + if (s == OCHAR) + break; + } assert(cp < g->must + g->mlen); - *cp++ = (RCHAR_T)OPND(s); + *cp++ = d; } assert(cp == g->must + g->mlen); *cp++ = '\0'; /* just on general principles */ @@ -1624,7 +1669,7 @@ scan = g->strip + 1; do { s = *scan++; - switch (OP(s)) { + switch (s) { case OPLUS_: plusnest++; break; @@ -1634,7 +1679,7 @@ plusnest--; break; } - } while (OP(s) != OEND); + } while (s != OEND); if (plusnest != 0) g->iflags |= BAD; return(maxnest); diff -urBw nvi-1.81.6.orig/regex/regex2.h nvi-1.81.6/regex/regex2.h --- nvi-1.81.6.orig/regex/regex2.h 2007-11-19 01:41:42.000000000 +0900 +++ nvi-1.81.6/regex/regex2.h 2008-09-01 05:58:30.000000000 +0900 @@ -75,36 +75,31 @@ * In state representations, an operator's bit is on to signify a state * immediately *preceding* "execution" of that operator. */ -typedef unsigned long sop; /* strip operator */ +typedef int sop; /* strip operator */ typedef int sopno; -#define OPRMASK 0xf8000000 -#define OPDMASK 0x07ffffff -#define OPSHIFT ((unsigned)27) -#define OP(n) ((n)&OPRMASK) -#define OPND(n) ((n)&OPDMASK) -#define SOP(op, opnd) ((op)|(opnd)) + /* operators meaning operand */ /* (back, fwd are offsets) */ -#define OEND (1UL< cset [ncsets] */ @@ -173,5 +169,5 @@ }; /* misc utilities */ -#define OUT (RCHAR_T_MAX+1) /* a non-character value */ -#define ISWORD(c) ((c <= 0xFF && isalnum(c)) || (c) == '_') +#define OUT WEOF /* a non-character value */ +#define ISWORD(c) (((UCHAR_T)c <= 0xFF && isalnum((unsigned char)c)) || (c) == '_') diff -urBw nvi-1.81.6.orig/regex/regfree.c nvi-1.81.6/regex/regfree.c --- nvi-1.81.6.orig/regex/regfree.c 2007-11-19 01:41:42.000000000 +0900 +++ nvi-1.81.6/regex/regfree.c 2008-09-01 05:57:20.000000000 +0900 @@ -69,6 +69,8 @@ if (g->strip != NULL) free((char *)g->strip); + if (g->stripdata != NULL) + free((char *)g->stripdata); if (g->sets != NULL) free((char *)g->sets); if (g->setbits != NULL)