diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2014-03-18 16:43:36 -0700 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-04-04 19:32:21 +0200 |
commit | 964ac38fb0dc84e05606b3abf6f7fcb887a62528 (patch) | |
tree | 8156877416e9b603391079cf9c5f29c6c3ad75d2 /src/corelib | |
parent | 8c0919a2863948ed8705893c574b481dcdc30ff2 (diff) |
Don't read before the beginning of the string
The code did discard the the data, so it wasn't affecting the comparison
result (tests added anyway), but it could cause crashes if the pointer
to the beginning of the data in the first 8 bytes of a page.
Change-Id: I618e68de329b65de34ef8c934934c3e631cc6c9f
Reported-By: Erik Verbruggen
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/tools/qstring.cpp | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 7d409708bb..79365b11b1 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -559,11 +559,13 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) } } - // we'll read uc[offset..offset+7] (16 bytes) and c[offset-8..offset+7] (16 bytes) +# ifdef Q_PROCESSOR_X86_64 + enum { MaxTailLength = 7 }; + // we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes) if (uc + offset + 7 < e) { - // same, but we'll throw away half the data - __m128i chunk = _mm_loadu_si128((__m128i*)(c + offset - 8)); - __m128i secondHalf = _mm_unpackhi_epi8(chunk, nullmask); + // same, but we're using an 8-byte load + __m128i chunk = _mm_cvtsi64_si128(*(long long *)(c + offset)); + __m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask); __m128i ucdata = _mm_loadu_si128((__m128i*)(uc + offset)); __m128i result = _mm_cmpeq_epi16(secondHalf, ucdata); @@ -577,6 +579,10 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) // still matched offset += 8; } +# else + // 32-bit, we can't do MOVQ to load 8 bytes + enum { MaxTailLength = 15 }; +# endif // reset uc and c uc += offset; @@ -584,7 +590,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) # ifdef Q_COMPILER_LAMBDA const auto &lambda = [=](int i) { return uc[i] - ushort(c[i]); }; - return UnrollTailLoop<7>::exec(e - uc, 0, lambda, lambda); + return UnrollTailLoop<MaxTailLength>::exec(e - uc, 0, lambda, lambda); # endif #endif |