summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclCmdMZ.c29
-rw-r--r--tests/string.test6
2 files changed, 27 insertions, 8 deletions
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index 30586b1..706d71c 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -2262,7 +2262,7 @@ StringRplcCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_UniChar *ustring;
- int first, last, length;
+ int first, last, length, end;
if (objc < 4 || objc > 5) {
Tcl_WrongNumArgs(interp, 1, objv, "string first last ?string?");
@@ -2270,20 +2270,33 @@ StringRplcCmd(
}
ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
- length--;
+ end = length - 1;
- if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK ||
- TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK){
+ if (TclGetIntForIndexM(interp, objv[2], end, &first) != TCL_OK ||
+ TclGetIntForIndexM(interp, objv[3], end, &last) != TCL_OK){
return TCL_ERROR;
}
- if ((last < first) || (last < 0) || (first > length)) {
+ /*
+ * The following test screens out most empty substrings as
+ * candidates for replacement. When they are detected, no
+ * replacement is done, and the result is the original string,
+ */
+ if ((last < 0) || /* Range ends before start of string */
+ (first > end) || /* Range begins after end of string */
+ (last < first)) { /* Range begins after it starts */
+
+ /*
+ * BUT!!! when (end < 0) -- an empty original string -- we can
+ * have (first <= end < 0 <= last) and an empty string is permitted
+ * to be replaced.
+ */
Tcl_SetObjResult(interp, objv[1]);
} else {
Tcl_Obj *resultPtr;
ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
- length--;
+ end = length-1;
if (first < 0) {
first = 0;
@@ -2293,9 +2306,9 @@ StringRplcCmd(
if (objc == 5) {
Tcl_AppendObjToObj(resultPtr, objv[4]);
}
- if (last < length) {
+ if (last < end) {
Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1,
- length - last);
+ end - last);
}
Tcl_SetObjResult(interp, resultPtr);
}
diff --git a/tests/string.test b/tests/string.test
index 39abd86..f3bb366 100644
--- a/tests/string.test
+++ b/tests/string.test
@@ -1294,6 +1294,12 @@ test string-14.16 {string replace} {
test string-14.17 {string replace} {
string replace abcdefghijklmnop end end-1
} {abcdefghijklmnop}
+test string-14.18 {string replace} {
+ string replace abcdefghijklmnop 10 9 XXX
+} {abcdefghijklmnop}
+test string-14.19 {string replace} {
+ string replace {} -1 0 A
+} A
test string-15.1 {string tolower too few args} {
list [catch {string tolower} msg] $msg