Bug 121027

Summary: Crash on long string
Product: WebKit Reporter: Vasiliy Baranov <vasiliy.baranov>
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Status: UNCONFIRMED ---    
Severity: Normal CC: ap, erights, ggaren, msaboff, oliver, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: 528+ (Nightly build)   
Hardware: PC   
OS: All   

Description Vasiliy Baranov 2013-09-09 03:04:01 PDT
The following script crashes the latest 32 bit Safari, WinLauncher, and, FWIW, Chrome 30.0.1599.22 beta-m:

    <script language="javascript">
    var s = "0123456789abcdef";
    while (true) {
      alert (s.length)
      s = s + s
    }
    </script>

The problem appears to be in the following code in JSC::stringLengthTrampolineGenerator():

    jit.load32(
        JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSString::offsetOfLength()),
        JSInterfaceJIT::regT2);

    JSInterfaceJIT::Jump failureCases3 = jit.branch32(
        JSInterfaceJIT::Above, JSInterfaceJIT::regT2, JSInterfaceJIT::TrustedImm32(INT_MAX));
    jit.move(JSInterfaceJIT::regT2, JSInterfaceJIT::regT0);

In case the length of the string is greater than INT_MAX, this code results in a call to cti_op_get_by_id_string_fail with ECX = <the length of the string>, which causes cti_op_get_by_id_string_fail to crash because cti_op_get_by_id_string_fail expects ECX to point to an object.

The following patch fixes the problem for me:

Index: JavaScriptCore/jit/ThunkGenerators.cpp
===================================================================
--- JavaScriptCore/jit/ThunkGenerators.cpp      (revision 150795)
+++ JavaScriptCore/jit/ThunkGenerators.cpp      (working copy)
@@ -198,11 +198,10 @@
     // Checks out okay! - get the length from the Ustring.
     jit.load32(
         JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSString::offsetOfLength()),
-        JSInterfaceJIT::regT2);
+        JSInterfaceJIT::regT0);

     JSInterfaceJIT::Jump failureCases3 = jit.branch32(
-        JSInterfaceJIT::Above, JSInterfaceJIT::regT2, JSInterfaceJIT::TrustedImm32(INT_MAX));
-    jit.move(JSInterfaceJIT::regT2, JSInterfaceJIT::regT0);
+        JSInterfaceJIT::Above, JSInterfaceJIT::regT0, JSInterfaceJIT::TrustedImm32(INT_MAX));
     jit.move(JSInterfaceJIT::TrustedImm32(JSValue::Int32Tag), JSInterfaceJIT::regT1);
 #endif // USE(JSVALUE64)
Comment 1 Radar WebKit Bug Importer 2013-09-09 09:34:31 PDT
<rdar://problem/14944560>