From bd41c9c239887b60b4b71f50835c978c66a3f0b6934ada97a1ac60a85ad2f292 Mon Sep 17 00:00:00 2001 From: Reinhard Max Date: Tue, 17 Jan 2023 11:26:15 +0000 Subject: [PATCH] - bsc#1206623: adopt upstream patch for an improved fix that does not remove the optimisation. OBS-URL: https://build.opensuse.org/package/show/devel:languages:tcl/tcl?expand=0&rev=151 --- tcl-string-compare.patch | 141 +++++++++++++++++++++++++++++++++------ tcl.changes | 6 ++ tcl.spec | 2 +- 3 files changed, 129 insertions(+), 20 deletions(-) diff --git a/tcl-string-compare.patch b/tcl-string-compare.patch index f15d3b7..9922ae8 100644 --- a/tcl-string-compare.patch +++ b/tcl-string-compare.patch @@ -1,30 +1,133 @@ -Index: generic/tclCmdMZ.c -================================================================== ---- generic/tclCmdMZ.c +--- generic/tclCmdMZ.c.orig +++ generic/tclCmdMZ.c -@@ -2752,23 +2752,11 @@ +@@ -2629,7 +2629,7 @@ StringEqualCmd( + */ + + objv += objc-2; +- match = TclStringCmp(objv[0], objv[1], 0, nocase, reqlength); ++ match = TclStringCmp(objv[0], objv[1], 1, nocase, reqlength); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match ? 0 : 1)); + return TCL_OK; + } +@@ -2702,8 +2702,8 @@ TclStringCmp( + Tcl_Obj *value2Ptr, + int checkEq, /* comparison is only for equality */ + int nocase, /* comparison is not case sensitive */ +- int reqlength) /* requested length; -1 to compare whole +- * strings */ ++ int reqlength) /* requested length in characters; -1 to ++ * compare whole strings */ + { + const char *s1, *s2; + int empty, length, match, s1len, s2len; +@@ -2731,10 +2731,10 @@ TclStringCmp( + } else if ((value1Ptr->typePtr == &tclStringType) + && (value2Ptr->typePtr == &tclStringType)) { + /* +- * Do a unicode-specific comparison if both of the args are of String ++ * Do a Unicode-specific comparison if both of the args are of String + * type. If the char length == byte length, we can do a memcmp. In + * benchmark testing this proved the most efficient check between the +- * unicode and string comparison operations. ++ * Unicode and string comparison operations. + */ + + if (nocase) { +@@ -2748,6 +2748,9 @@ TclStringCmp( + && (value1Ptr->bytes != NULL) + && (s2len == value2Ptr->length) + && (value2Ptr->bytes != NULL)) { ++ /* each byte represents one character so s1l3n, s2l3n, and ++ * reqlength are in both bytes and characters ++ */ + s1 = value1Ptr->bytes; s2 = value2Ptr->bytes; memCmpFn = memcmp; - } else { - s1 = (char *) Tcl_GetUnicode(value1Ptr); +@@ -2756,14 +2759,17 @@ TclStringCmp( s2 = (char *) Tcl_GetUnicode(value2Ptr); -- if ( --#if defined(WORDS_BIGENDIAN) && (TCL_UTF_MAX != 4) + if ( + #if defined(WORDS_BIGENDIAN) && (TCL_UTF_MAX != 4) - 1 --#else ++ 1 + #else - checkEq --#endif /* WORDS_BIGENDIAN */ ++ checkEq + #endif /* WORDS_BIGENDIAN */ - ) { -- memCmpFn = memcmp; -- s1len *= sizeof(Tcl_UniChar); -- s2len *= sizeof(Tcl_UniChar); -- } else { -- memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp; -- } -+ memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp; ++ ) { + memCmpFn = memcmp; + s1len *= sizeof(Tcl_UniChar); + s2len *= sizeof(Tcl_UniChar); ++ if (reqlength > 0) { ++ reqlength *= sizeof(Tcl_UniChar); ++ } + } else { + memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp; + } +@@ -2805,7 +2811,7 @@ TclStringCmp( + s2 = TclGetStringFromObj(value2Ptr, &s2len); + } + +- if (!nocase && checkEq) { ++ if (!nocase && checkEq && reqlength < 0) { + /* + * When we have equal-length we can check only for (in)equality. + * We can use memcmp() in all (n)eq cases because we don't need to +@@ -2826,24 +2832,28 @@ TclStringCmp( + s1len = Tcl_NumUtfChars(s1, s1len); + s2len = Tcl_NumUtfChars(s2, s2len); + memCmpFn = (memCmpFn_t) +- (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp); ++ (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp); } } + } + ++ /* At this point s1len, s2len, and reqlength should by now have been ++ * adjusted so that they are all in the units expected by the selected ++ * comparison function. ++ */ ++ + length = (s1len < s2len) ? s1len : s2len; + if (reqlength > 0 && reqlength < length) { + length = reqlength; + } else if (reqlength < 0) { + /* +- * The requested length is negative, so we ignore it by setting it to +- * length + 1 so we correct the match var. ++ * The requested length is negative, so ignore it by setting it to ++ * length + 1 to correct the match var. + */ +- + reqlength = length + 1; + } + +- if (checkEq && (s1len != s2len)) { ++ if (checkEq && reqlength < 0 && (s1len != s2len)) { + match = 1; /* This will be reversed below. */ } else { /* - * Get the string representations, being careful in case we have - +--- tests/stringComp.test.orig ++++ tests/stringComp.test +@@ -100,7 +100,7 @@ foreach {tname tbody tresult tcode} { + {unicode} {string compare \334 \u00fc} -1 {} + {unicode} {string compare \334\334\334\374\374 \334\334\334\334\334} 1 {} + {high bit} { +- # This test will fail if the underlying comparison ++ # This test fails if the underlying comparison + # is using signed chars instead of unsigned chars. + # (like SunOS's default memcmp thus the compat/memcmp.c) + string compare "\x80" "@" +@@ -156,10 +156,10 @@ foreach {tname tbody tresult tcode} { + {-nocase null strings} { + string compare -nocase foo "" + } 1 {} +- {with length, unequal strings} { ++ {with length, unequal strings, partial first string} { + string compare -length 2 abc abde + } 0 {} +- {with length, unequal strings} { ++ {with length, unequal strings 2, full first string} { + string compare -length 2 ab abde + } 0 {} + {with NUL character vs. other ASCII} { diff --git a/tcl.changes b/tcl.changes index a38f5c7..fcde941 100644 --- a/tcl.changes +++ b/tcl.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Jan 17 11:21:29 UTC 2023 - Reinhard Max + +- bsc#1206623: adopt upstream patch for an improved fix that does + not remove the optimisation. + ------------------------------------------------------------------- Fri Dec 23 15:50:47 UTC 2022 - Reinhard Max diff --git a/tcl.spec b/tcl.spec index c364601..4b913c7 100644 --- a/tcl.spec +++ b/tcl.spec @@ -1,7 +1,7 @@ # # spec file for package tcl # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed