Module Name: src Committed By: rin Date: Sun Nov 12 16:10:59 UTC 2017
Modified Files: src/external/bsd/tre/dist/lib: regexec.c Log Message: Make REG_STARTEND for tre_regcomp() working actually: - correct string length - shift pmatch after pattern matching - check validity of arguments Do the same thing for tre_regwcomp() To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/external/bsd/tre/dist/lib/regexec.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/tre/dist/lib/regexec.c diff -u src/external/bsd/tre/dist/lib/regexec.c:1.4 src/external/bsd/tre/dist/lib/regexec.c:1.5 --- src/external/bsd/tre/dist/lib/regexec.c:1.4 Sat Nov 5 22:39:13 2011 +++ src/external/bsd/tre/dist/lib/regexec.c Sun Nov 12 16:10:59 2017 @@ -198,22 +198,34 @@ int tre_regexec(const regex_t *preg, const char *str, size_t nmatch, regmatch_t pmatch[], int eflags) { - const char *newstr; - unsigned newflags; - size_t newlen; + size_t shift, len, i; + int startend, ret; + tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD; + regmatch_t *p; if (eflags & REG_STARTEND) { - /* LINTED */ - newstr = &str[pmatch[0].rm_so]; - /* LINTED */ - newlen = pmatch[0].rm_eo; - newflags = (unsigned)(eflags & ~REG_STARTEND); + if (pmatch == NULL || pmatch->rm_so < 0 + || pmatch->rm_so > pmatch->rm_eo) + return REG_INVARG; + str += shift = pmatch->rm_so; + len = pmatch->rm_eo - pmatch->rm_so; + eflags = (unsigned)(eflags & ~REG_STARTEND); + startend = 1; } else { - newstr = str; - newlen = (size_t)-1; - newflags = (unsigned)eflags; + len = (size_t)-1; + startend = 0; } - return tre_regnexec(preg, newstr, newlen, nmatch, pmatch, (int)newflags); + + ret = tre_regnexec(preg, str, len, nmatch, pmatch, eflags); + + if (!ret && !(tnfa->cflags & REG_NOSUB) && startend) { + for (i = nmatch, p = pmatch; i > 0; p++, i--) { + if (p->rm_so >= 0) p->rm_so += shift; + if (p->rm_eo >= 0) p->rm_eo += shift; + } + } + + return ret; } @@ -231,7 +243,34 @@ int tre_regwexec(const regex_t *preg, const wchar_t *str, size_t nmatch, regmatch_t pmatch[], int eflags) { - return tre_regwnexec(preg, str, (unsigned)-1, nmatch, pmatch, eflags); + size_t shift, len, i; + int startend, ret; + tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD; + regmatch_t *p; + + if (eflags & REG_STARTEND) { + if (pmatch == NULL || pmatch->rm_so < 0 + || pmatch->rm_so > pmatch->rm_eo) + return REG_INVARG; + str += shift = pmatch->rm_so; + len = pmatch->rm_eo - pmatch->rm_so; + eflags = (unsigned)(eflags & ~REG_STARTEND); + startend = 1; + } else { + len = (size_t)-1; + startend = 0; + } + + ret = tre_regwnexec(preg, str, len, nmatch, pmatch, eflags); + + if (!ret && !(tnfa->cflags & REG_NOSUB) && startend) { + for (i = nmatch, p = pmatch; i > 0; p++, i--) { + if (p->rm_so >= 0) p->rm_so += shift; + if (p->rm_eo >= 0) p->rm_eo += shift; + } + } + + return ret; } #endif /* TRE_WCHAR */