From d4e2ae119e3f6d6e5d430cf810ea4dc396ecd9b7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 21 Jan 2022 14:44:58 +0000 Subject: Undo part of [26539e78a7]. Although Tcl_GetRange() does it's own parameter check, it's caller doesn't have to do it any more. However, put back these check, better not depend on the improved behavior of Tcl_GetRange (yet). This gives the freedom to bring back Tcl_GetRange() to how it was in Tcl 8.6.10, if desired --- generic/tclCmdMZ.c | 20 +++++++++++--------- generic/tclExecute.c | 26 ++++++++++++++++++++++---- generic/tclStringObj.c | 7 ++++--- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index bf75d44..34fd6bf 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -394,14 +394,10 @@ Tcl_RegexpObjCmd( newPtr = Tcl_NewListObj(2, objs); } else { - if (i <= info.nsubs) { - if (info.matches[i].end <= 0) { - TclNewObj(newPtr); - } else { - newPtr = Tcl_GetRange(objPtr, - offset + info.matches[i].start, - offset + info.matches[i].end - 1); - } + if ((i <= info.nsubs) && (info.matches[i].end > 0)) { + newPtr = Tcl_GetRange(objPtr, + offset + info.matches[i].start, + offset + info.matches[i].end - 1); } else { TclNewObj(newPtr); } @@ -2187,7 +2183,13 @@ StringRangeCmd( return TCL_ERROR; } - if (last >= 0) { + if (first < 0) { + first = 0; + } + if (last >= length) { + last = length; + } + if (last >= first) { Tcl_SetObjResult(interp, Tcl_GetRange(objv[1], first, last)); } return TCL_OK; diff --git a/generic/tclExecute.c b/generic/tclExecute.c index a3b0401..e5a6b71 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5609,10 +5609,16 @@ TEBCresume( goto gotError; } - if (toIdx < 0) { - TclNewObj(objResultPtr); - } else { + if (fromIdx < 0) { + fromIdx = 0; + } + if (toIdx >= length) { + toIdx = length; + } + if (toIdx >= fromIdx) { objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx); + } else { + TclNewObj(objResultPtr); } TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); NEXT_INST_V(1, 3, 1); @@ -5646,6 +5652,13 @@ TEBCresume( } toIdx = TclIndexDecode(toIdx, length - 1); + if (toIdx < 0) { + goto emptyRange; + } else if (toIdx >= length) { + toIdx = length - 1; + } + + assert ( toIdx >= 0 && toIdx < length ); /* assert ( fromIdx != TCL_INDEX_BEFORE ); @@ -5659,8 +5672,13 @@ TEBCresume( if (fromIdx == TCL_INDEX_AFTER) { goto emptyRange; } + fromIdx = TclIndexDecode(fromIdx, length - 1); - if (toIdx >= 0) { + if (fromIdx < 0) { + fromIdx = 0; + } + + if (fromIdx <= toIdx) { objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx); } else { emptyRange: diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index b4f05dd..9e0e4af 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -819,6 +819,7 @@ Tcl_GetRange( FillUnicodeRep(objPtr); stringPtr = GET_STRING(objPtr); } + if (last < 0 || last >= stringPtr->numChars) { last = stringPtr->numChars - 1; } @@ -829,12 +830,12 @@ Tcl_GetRange( #if TCL_UTF_MAX == 4 /* See: bug [11ae2be95dac9417] */ if ((first > 0) && ((stringPtr->unicode[first] & 0xFC00) == 0xDC00) - && ((stringPtr->unicode[first-1] & 0xFC00) == 0xD800)) { + && ((stringPtr->unicode[first-1] & 0xFC00) == 0xD800)) { ++first; } if ((last + 1 < stringPtr->numChars) - && ((stringPtr->unicode[last+1] & 0xFC00) == 0xDC00) - && ((stringPtr->unicode[last] & 0xFC00) == 0xD800)) { + && ((stringPtr->unicode[last+1] & 0xFC00) == 0xDC00) + && ((stringPtr->unicode[last] & 0xFC00) == 0xD800)) { ++last; } #endif -- cgit v0.12