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 */

Reply via email to