From 9def501433e80e1a45c0d7888b9ceba4e32ca1fa Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 18 Apr 2016 23:27:12 +0200 Subject: QString: Avoid searching for a needle which is longer than the hay Avoid incurring the cost of converting the latin1 data in that case. Several existing QString unit tests excercise the new code path. Task-number: QTBUG-52617 Change-Id: I27256d9e7db34f09543e244a79d754ff7932f0d0 Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/corelib/tools/qstring.cpp') diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 10d3441d2c..983d1213d9 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -10005,6 +10005,9 @@ static inline int qt_find_latin1_string(const QChar *haystack, int size, QLatin1String needle, int from, Qt::CaseSensitivity cs) { + if (size < needle.size()) + return -1; + const char *latin1 = needle.latin1(); int len = needle.size(); QVarLengthArray s(len); -- cgit v1.2.3 From a1e3a0daed6c056c3b957151605f0f277fd38d3c Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 25 Mar 2016 10:40:44 +0100 Subject: QString: Fix UBs (signed overflow) in hashed string search Similar change to 390ea21873cf229447c2dcaea85a40e472fab03c, but more extensive because the hash variables were not, yet, of unsigned type. This brings the three hashed string search algorithms in QtBase (in QString, QByteArray and QByteArrayMatcher) in line again. Found by UBSan, fixing the following bunch of errors: tools/qstring.cpp:3080:38: runtime error: left shift of negative value -1291179264 tools/qstring.cpp:3081:42: runtime error: left shift of negative value -1291179264 tools/qstring.cpp:3091:13: runtime error: left shift of 73 by 26 places cannot be represented in type 'int' tools/qstring.cpp:3091:13: runtime error: left shift of negative value -1255957171 tools/qstring.cpp:3091:13: runtime error: signed integer overflow: 1783052986 - -1207959552 cannot be represented in type 'int' tools/qstring.cpp:3097:37: runtime error: left shift of negative value -1298753576 tools/qstring.cpp:3098:41: runtime error: left shift of negative value -1298753576 tools/qstring.cpp:3107:13: runtime error: left shift of negative value -1508912760 tools/qstring.cpp:3158:38: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3159:42: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3169:13: runtime error: left shift of negative value -1657715810 tools/qstring.cpp:3173:38: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3174:42: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3183:13: runtime error: left shift of negative value -1657715810 Change-Id: I1436eb61369919df9fe34251f863dd54fb58af98 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qstring.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/corelib/tools/qstring.cpp') diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 983d1213d9..6bbaf05fef 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -705,8 +705,8 @@ static int findChar(const QChar *str, int len, QChar ch, int from, } #define REHASH(a) \ - if (sl_minus_1 < (int)sizeof(int) * CHAR_BIT) \ - hashHaystack -= (a) << sl_minus_1; \ + if (sl_minus_1 < sizeof(uint) * CHAR_BIT) \ + hashHaystack -= uint(a) << sl_minus_1; \ hashHaystack <<= 1 inline bool qIsUpper(char ch) @@ -3072,8 +3072,9 @@ int qFindString( const ushort *needle = (const ushort *)needle0; const ushort *haystack = (const ushort *)haystack0 + from; const ushort *end = (const ushort *)haystack0 + (l-sl); - const int sl_minus_1 = sl-1; - int hashNeedle = 0, hashHaystack = 0, idx; + const uint sl_minus_1 = sl - 1; + uint hashNeedle = 0, hashHaystack = 0; + int idx; if (cs == Qt::CaseSensitive) { for (idx = 0; idx < sl; ++idx) { @@ -3148,10 +3149,11 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee const ushort *end = haystack; haystack += from; - const int sl_minus_1 = sl-1; + const uint sl_minus_1 = sl - 1; const ushort *n = needle+sl_minus_1; const ushort *h = haystack+sl_minus_1; - int hashNeedle = 0, hashHaystack = 0, idx; + uint hashNeedle = 0, hashHaystack = 0; + int idx; if (cs == Qt::CaseSensitive) { for (idx = 0; idx < sl; ++idx) { -- cgit v1.2.3