summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2018-12-13 20:01:34 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2018-12-13 20:01:34 (GMT)
commit9c5dc4c207e6610aa3d55e2d4d081779848a21c6 (patch)
treefc9cd49a7e54859c46ce5c62037c410d47c2211a /generic/tclStringObj.c
parent1961633531b70d5a6e627f86153f4d15e722ea8b (diff)
downloadtcl-9c5dc4c207e6610aa3d55e2d4d081779848a21c6.zip
tcl-9c5dc4c207e6610aa3d55e2d4d081779848a21c6.tar.gz
tcl-9c5dc4c207e6610aa3d55e2d4d081779848a21c6.tar.bz2
Fix 2 TIP #502 corner-cases. Those corner-cases where (probably) always wrong on 32-bit systems, but now we have a TIP describing how it's expected to behave!
Thanks to Emiliano for noticing and reporting it. Added 6 test-cases for completeness, 2 of them failed before this fix. Also optimize TclStringLast() a bit, implementing the pre-condition tests as in TclStringFirst().
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 4e6cdc5..72ca7cd 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -3568,6 +3568,10 @@ TclStringFirst(
/* Find bytes in bytes */
bh = Tcl_GetByteArrayFromObj(haystack, &lh);
+ if ((lh < ln) || (start > lh - ln)) {
+ /* Don't start the loop if there cannot be a valid answer */
+ return -1;
+ }
end = bh + lh;
try = bh + start;
@@ -3610,6 +3614,10 @@ TclStringFirst(
Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
uh = Tcl_GetUnicodeFromObj(haystack, &lh);
+ if ((lh < ln) || (start > lh - ln)) {
+ /* Don't start the loop if there cannot be a valid answer */
+ return -1;
+ }
end = uh + lh;
for (try = uh + start; try + ln <= end; try++) {
@@ -3658,20 +3666,19 @@ TclStringLast(
return -1;
}
- lh = Tcl_GetCharLength(haystack);
- if (last >= lh) {
- last = lh - 1;
- }
-
- if (last < ln - 1) {
- return -1;
- }
-
if (TclIsPureByteArray(needle) && TclIsPureByteArray(haystack)) {
unsigned char *try, *bh = Tcl_GetByteArrayFromObj(haystack, &lh);
unsigned char *bn = Tcl_GetByteArrayFromObj(needle, &ln);
+ if (last >= lh) {
+ last = lh - 1;
+ }
+ if (last + 1 < ln) {
+ /* Don't start the loop if there cannot be a valid answer */
+ return -1;
+ }
try = bh + last + 1 - ln;
+
while (try >= bh) {
if ((*try == bn[0])
&& (0 == memcmp(try+1, bn+1, ln-1))) {
@@ -3686,6 +3693,13 @@ TclStringLast(
Tcl_UniChar *try, *uh = Tcl_GetUnicodeFromObj(haystack, &lh);
Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
+ if (last >= lh) {
+ last = lh - 1;
+ }
+ if (last + 1 < ln) {
+ /* Don't start the loop if there cannot be a valid answer */
+ return -1;
+ }
try = uh + last + 1 - ln;
while (try >= uh) {
if ((*try == un[0])