summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2018-12-13 21:01:58 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2018-12-13 21:01:58 (GMT)
commit4cbeaa529ce09f93337280323fb52da94c58185f (patch)
tree7b1acdb835a036afa6498798415f16363ecb1202 /generic/tclStringObj.c
parentd233b14db6836d4497e34d2b3e981390b8fcba9c (diff)
parent9c5dc4c207e6610aa3d55e2d4d081779848a21c6 (diff)
downloadtcl-4cbeaa529ce09f93337280323fb52da94c58185f.zip
tcl-4cbeaa529ce09f93337280323fb52da94c58185f.tar.gz
tcl-4cbeaa529ce09f93337280323fb52da94c58185f.tar.bz2
Merge 8.7, and make all test-cases pass.
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 5b51ca5..4ca7b62 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -3471,7 +3471,7 @@ TclStringFirst(
/* We don't find empty substrings. Bizarre!
* Whenever this routine is turned into a proper substring
* finder, change to `return start` after limits imposed. */
- return -1;
+ return TCL_IO_FAILURE;
}
if (TclIsPureByteArray(needle) && TclIsPureByteArray(haystack)) {
@@ -3480,6 +3480,10 @@ TclStringFirst(
/* Find bytes in bytes */
bh = TclGetByteArrayFromObj(haystack, &lh);
+ if ((lh < ln) || (start > lh - ln)) {
+ /* Don't start the loop if there cannot be a valid answer */
+ return TCL_IO_FAILURE;
+ }
end = bh + lh;
try = bh + start;
@@ -3492,7 +3496,7 @@ TclStringFirst(
try = memchr(try, bn[0], (end + 1 - ln) - try);
if (try == NULL) {
/* Leading byte not found -> needle cannot be found. */
- return -1;
+ return TCL_IO_FAILURE;
}
/* Leading byte found, check rest of needle. */
if (0 == memcmp(try+1, bn+1, ln-1)) {
@@ -3502,7 +3506,7 @@ TclStringFirst(
/* Rest of needle match failed; Iterate to continue search. */
try++;
}
- return -1;
+ return TCL_IO_FAILURE;
}
/*
@@ -3522,6 +3526,10 @@ TclStringFirst(
Tcl_UniChar *un = TclGetUnicodeFromObj(needle, &ln);
uh = TclGetUnicodeFromObj(haystack, &lh);
+ if ((lh < ln) || (start > lh - ln)) {
+ /* Don't start the loop if there cannot be a valid answer */
+ return TCL_IO_FAILURE;
+ }
end = uh + lh;
for (try = uh + start; try + ln <= end; try++) {
@@ -3530,7 +3538,7 @@ TclStringFirst(
return (try - uh);
}
}
- return -1;
+ return TCL_IO_FAILURE;
}
}
@@ -3570,20 +3578,19 @@ TclStringLast(
return TCL_IO_FAILURE;
}
- lh = Tcl_GetCharLength(haystack);
- if (last >= lh) {
- last = lh - 1;
- }
-
- if (last < ln - 1) {
- return TCL_IO_FAILURE;
- }
-
if (TclIsPureByteArray(needle) && TclIsPureByteArray(haystack)) {
unsigned char *try, *bh = TclGetByteArrayFromObj(haystack, &lh);
unsigned char *bn = TclGetByteArrayFromObj(needle, &ln);
+ if (last + 1 >= lh + 1) {
+ last = lh - 1;
+ }
+ if (last + 1 < ln) {
+ /* Don't start the loop if there cannot be a valid answer */
+ return TCL_IO_FAILURE;
+ }
try = bh + last + 1 - ln;
+
while (try >= bh) {
if ((*try == bn[0])
&& (0 == memcmp(try+1, bn+1, ln-1))) {
@@ -3591,13 +3598,20 @@ TclStringLast(
}
try--;
}
- return -1;
+ return TCL_IO_FAILURE;
}
{
Tcl_UniChar *try, *uh = TclGetUnicodeFromObj(haystack, &lh);
Tcl_UniChar *un = TclGetUnicodeFromObj(needle, &ln);
+ if (last + 1 >= lh + 1) {
+ last = lh - 1;
+ }
+ if (last + 1 < ln) {
+ /* Don't start the loop if there cannot be a valid answer */
+ return TCL_IO_FAILURE;
+ }
try = uh + last + 1 - ln;
while (try >= uh) {
if ((*try == un[0])