indexOf and lastIndexOf shouldn't resolve ropes when needle is longer than haystack
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Feb 2014 05:30:09 +0000 (05:30 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Feb 2014 05:30:09 +0000 (05:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=129466

Reviewed by Michael Saboff.

Refactored the code to avoid calling JSString::value when needle is longer than haystack.

* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncIndexOf):
(JSC::stringProtoFuncLastIndexOf):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@164851 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/StringPrototype.cpp

index 392a0324cfa34e70beaa1b3dc9d7e82257ed2dd8..7f2b58940b7894c674008bc822a5a51a4f5181d8 100644 (file)
@@ -1,3 +1,16 @@
+2014-02-27  Ryosuke Niwa  <rniwa@webkit.org>
+
+        indexOf and lastIndexOf shouldn't resolve ropes when needle is longer than haystack
+        https://bugs.webkit.org/show_bug.cgi?id=129466
+
+        Reviewed by Michael Saboff.
+
+        Refactored the code to avoid calling JSString::value when needle is longer than haystack.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncIndexOf):
+        (JSC::stringProtoFuncLastIndexOf):
+
 2014-02-27  Timothy Hatcher  <timothy@apple.com>
 
         Improve how ContentSearchUtilities::lineEndings works by supporting the three common line endings.
index 710e1d5d251f62ffbbd4097a117d188a96b8c8d8..669feefff715ba850e4c986d8710cd53c5dc2706 100644 (file)
@@ -752,18 +752,16 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec)
     JSValue thisValue = exec->hostThisValue();
     if (!checkObjectCoercible(thisValue))
         return throwVMTypeError(exec);
-    String s = thisValue.toString(exec)->value(exec);
 
     JSValue a0 = exec->argument(0);
     JSValue a1 = exec->argument(1);
-    String u2 = a0.toString(exec)->value(exec);
 
-    size_t result;
-    if (a1.isUndefined())
-        result = s.find(u2);
-    else {
-        unsigned pos;
-        int len = s.length();
+    JSString* thisJSString = thisValue.toString(exec);
+    JSString* otherJSString = a0.toString(exec);
+
+    unsigned pos = 0;
+    if (!a1.isUndefined()) {
+        int len = thisJSString->length();
         if (a1.isUInt32())
             pos = std::min<uint32_t>(a1.asUInt32(), len);
         else {
@@ -774,9 +772,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec)
                 dpos = len;
             pos = static_cast<unsigned>(dpos);
         }
-        result = s.find(u2, pos);
     }
 
+    if (thisJSString->length() < otherJSString->length() + pos)
+        return JSValue::encode(jsNumber(-1));
+
+    size_t result = thisJSString->value(exec).find(otherJSString->value(exec), pos);
     if (result == notFound)
         return JSValue::encode(jsNumber(-1));
     return JSValue::encode(jsNumber(result));
@@ -787,25 +788,33 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec)
     JSValue thisValue = exec->hostThisValue();
     if (!checkObjectCoercible(thisValue))
         return throwVMTypeError(exec);
-    String s = thisValue.toString(exec)->value(exec);
-    int len = s.length();
 
     JSValue a0 = exec->argument(0);
     JSValue a1 = exec->argument(1);
 
-    String u2 = a0.toString(exec)->value(exec);
+    JSString* thisJSString = thisValue.toString(exec);
+    unsigned len = thisJSString->length();
+    JSString* otherJSString = a0.toString(exec);
+
     double dpos = a1.toIntegerPreserveNaN(exec);
+    unsigned startPosition;
     if (dpos < 0)
-        dpos = 0;
+        startPosition = 0;
     else if (!(dpos <= len)) // true for NaN
-        dpos = len;
+        startPosition = len;
+    else
+        startPosition = static_cast<unsigned>(dpos);
+
+    if (len < otherJSString->length())
+        return JSValue::encode(jsNumber(-1));
 
+    String thisString = thisJSString->value(exec);
+    String otherString = otherJSString->value(exec);
     size_t result;
-    unsigned startPosition = static_cast<unsigned>(dpos);
     if (!startPosition)
-        result = s.startsWith(u2) ? 0 : notFound;
+        result = thisString.startsWith(otherString) ? 0 : notFound;
     else
-        result = s.reverseFind(u2, startPosition);
+        result = thisString.reverseFind(otherString, startPosition);
     if (result == notFound)
         return JSValue::encode(jsNumber(-1));
     return JSValue::encode(jsNumber(result));