From bef0fd5fe9bdcdfa6eb9f0e14fa096038f391139 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 5 May 2014 15:01:10 +0200 Subject: Android: Fix crash in String.replace() in release builds When enabling optimizations in the compiler, it produces bogus code for the regExp->value deref in the line nMatchOffsets += regExp->value->captureCount() * 2 This is a random refactoring to work around the compiler bug. The only line that actually needs to be touched is the one mentioned above, but I replaced all uses of regExp->value so that it wouldn't look too weird. Task-number: QTBUG-38692 Change-Id: Ib33a523a86ce51ebc6c7095a803fedaebcaa8e63 Reviewed-by: Lars Knoll Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4stringobject.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 7c38ae4f01..f1e51703a8 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -508,21 +508,24 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx) Scoped regExp(scope, searchValue); if (regExp) { uint offset = 0; + + // We extract the pointer here to work around a compiler bug on Android. + Scoped re(scope, regExp->value); while (true) { int oldSize = nMatchOffsets; - if (allocatedMatchOffsets < nMatchOffsets + regExp->value->captureCount() * 2) { - allocatedMatchOffsets = qMax(allocatedMatchOffsets * 2, nMatchOffsets + regExp->value->captureCount() * 2); + if (allocatedMatchOffsets < nMatchOffsets + re->captureCount() * 2) { + allocatedMatchOffsets = qMax(allocatedMatchOffsets * 2, nMatchOffsets + re->captureCount() * 2); uint *newOffsets = (uint *)malloc(allocatedMatchOffsets*sizeof(uint)); memcpy(newOffsets, matchOffsets, nMatchOffsets*sizeof(uint)); if (matchOffsets != _matchOffsets) free(matchOffsets); matchOffsets = newOffsets; } - if (regExp->value->match(string, offset, matchOffsets + oldSize) == JSC::Yarr::offsetNoMatch) { + if (re->match(string, offset, matchOffsets + oldSize) == JSC::Yarr::offsetNoMatch) { nMatchOffsets = oldSize; break; } - nMatchOffsets += regExp->value->captureCount() * 2; + nMatchOffsets += re->captureCount() * 2; if (!regExp->global) break; offset = qMax(offset + 1, matchOffsets[oldSize + 1]); -- cgit v1.2.3