[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756

barraclough at apple.com barraclough at apple.com
Fri Feb 26 22:25:56 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 1b4facfa85728c06dc4b99c2d6c647af39acb8a9
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Feb 19 23:36:09 2010 +0000

    JSString::getIndex() calls value() to resolve the string value (is a rope)
    to a UString, then passes the result to jsSingleCharacterSubstring without
    checking for an exception.  In case of out-of-memory the returned UString
    is null(), which may result in an out-of-buounds substring being created.
    This is bad.
    
    Reviewed by Oliver Hunt.
    
    Simple fix is to be able to get an index from a rope without resolving to
    UString.  This may be a useful optimization in some test cases.
    
    The same bug exists in some other methods is JSString, these can be fixed
    by changing them to call getIndex().
    
    * runtime/JSString.cpp:
    (JSC::JSString::resolveRope):
    (JSC::JSString::getStringPropertyDescriptor):
    * runtime/JSString.h:
    (JSC::jsSingleCharacterSubstring):
    (JSC::JSString::getIndex):
    (JSC::jsSingleCharacterString):
    (JSC::JSString::getStringPropertySlot):
    * runtime/UStringImpl.cpp:
    (JSC::singleCharacterSubstring):
    * runtime/UStringImpl.h:
    (JSC::UStringImpl::singleCharacterSubstring):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55035 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 3d1a925..b1e4d60 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,32 @@
+2010-02-19  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        JSString::getIndex() calls value() to resolve the string value (is a rope)
+        to a UString, then passes the result to jsSingleCharacterSubstring without
+        checking for an exception.  In case of out-of-memory the returned UString
+        is null(), which may result in an out-of-buounds substring being created.
+        This is bad.
+
+        Simple fix is to be able to get an index from a rope without resolving to
+        UString.  This may be a useful optimization in some test cases.
+
+        The same bug exists in some other methods is JSString, these can be fixed
+        by changing them to call getIndex().
+
+        * runtime/JSString.cpp:
+        (JSC::JSString::resolveRope):
+        (JSC::JSString::getStringPropertyDescriptor):
+        * runtime/JSString.h:
+        (JSC::jsSingleCharacterSubstring):
+        (JSC::JSString::getIndex):
+        (JSC::jsSingleCharacterString):
+        (JSC::JSString::getStringPropertySlot):
+        * runtime/UStringImpl.cpp:
+        (JSC::singleCharacterSubstring):
+        * runtime/UStringImpl.h:
+        (JSC::UStringImpl::singleCharacterSubstring):
+
 2010-02-19  Oliver Hunt  <oliver at apple.com>
 
         RS = Gavin Barraclough.
diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp
index a72457e..d155b69 100644
--- a/JavaScriptCore/runtime/JSString.cpp
+++ b/JavaScriptCore/runtime/JSString.cpp
@@ -50,13 +50,6 @@ void JSString::resolveRope(ExecState* exec) const
     if (PassRefPtr<UStringImpl> newImpl = UStringImpl::tryCreateUninitialized(m_length, buffer))
         m_value = newImpl;
     else {
-        for (unsigned i = 0; i < m_fiberCount; ++i) {
-            m_other.m_fibers[i]->deref();
-            m_other.m_fibers[i] = 0;
-        }
-        m_fiberCount = 0;
-        ASSERT(!isRope());
-        ASSERT(m_value == UString());
         throwOutOfMemoryError(exec);
         return;
     }
@@ -187,7 +180,7 @@ bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& pr
     bool isStrictUInt32;
     unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
     if (isStrictUInt32 && i < m_length) {
-        descriptor.setDescriptor(jsSingleCharacterSubstring(exec, value(exec), i), DontDelete | ReadOnly);
+        descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly);
         return true;
     }
     
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index 0162282..91eeee0 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -41,7 +41,6 @@ namespace JSC {
 
     JSString* jsSingleCharacterString(JSGlobalData*, UChar);
     JSString* jsSingleCharacterString(ExecState*, UChar);
-    JSString* jsSingleCharacterSubstring(JSGlobalData*, const UString&, unsigned offset);
     JSString* jsSingleCharacterSubstring(ExecState*, const UString&, unsigned offset);
     JSString* jsSubstring(JSGlobalData*, const UString&, unsigned offset, unsigned length);
     JSString* jsSubstring(ExecState*, const UString&, unsigned offset, unsigned length);
@@ -365,8 +364,10 @@ namespace JSC {
         return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(&c, 1)));
     }
 
-    inline JSString* jsSingleCharacterSubstring(JSGlobalData* globalData, const UString& s, unsigned offset)
+    inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset)
     {
+        JSGlobalData* globalData = &exec->globalData();
+
         ASSERT(offset < static_cast<unsigned>(s.size()));
         UChar c = s.data()[offset];
         if (c <= 0xFF)
@@ -391,7 +392,21 @@ namespace JSC {
     inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
     {
         ASSERT(canGetIndex(i));
-        return jsSingleCharacterSubstring(&exec->globalData(), value(exec), i);
+        if (!isRope())
+            return jsSingleCharacterSubstring(exec, m_value, i);
+
+        if (i < m_other.m_fibers[0]->length())
+            return jsString(exec, singleCharacterSubstring(m_other.m_fibers[0], i));
+        i -= m_other.m_fibers[0]->length();
+
+        ASSERT(m_fiberCount >= 2);
+        if (i < m_other.m_fibers[1]->length())
+            return jsString(exec, singleCharacterSubstring(m_other.m_fibers[1], i));
+        i -= m_other.m_fibers[1]->length();
+
+        ASSERT(m_fiberCount == 3);
+        ASSERT(i < m_other.m_fibers[2]->length());
+        return jsString(exec, singleCharacterSubstring(m_other.m_fibers[2], i));
     }
 
     inline JSString* jsString(JSGlobalData* globalData, const UString& s)
@@ -445,7 +460,6 @@ namespace JSC {
     inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); }
     inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); }
     inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); }
-    inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset) { return jsSingleCharacterSubstring(&exec->globalData(), s, offset); }
     inline JSString* jsSubstring(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); }
     inline JSString* jsNontrivialString(ExecState* exec, const UString& s) { return jsNontrivialString(&exec->globalData(), s); }
     inline JSString* jsNontrivialString(ExecState* exec, const char* s) { return jsNontrivialString(&exec->globalData(), s); }
@@ -461,7 +475,7 @@ namespace JSC {
         bool isStrictUInt32;
         unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
         if (isStrictUInt32 && i < m_length) {
-            slot.setValue(jsSingleCharacterSubstring(exec, value(exec), i));
+            slot.setValue(getIndex(exec, i));
             return true;
         }
 
@@ -471,7 +485,7 @@ namespace JSC {
     ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
     {
         if (propertyName < m_length) {
-            slot.setValue(jsSingleCharacterSubstring(exec, value(exec), propertyName));
+            slot.setValue(getIndex(exec, propertyName));
             return true;
         }
 
diff --git a/JavaScriptCore/runtime/UStringImpl.cpp b/JavaScriptCore/runtime/UStringImpl.cpp
index b7d9a40..aeecf47 100644
--- a/JavaScriptCore/runtime/UStringImpl.cpp
+++ b/JavaScriptCore/runtime/UStringImpl.cpp
@@ -149,4 +149,24 @@ void URopeImpl::destructNonRecursive()
     }
 }
 
+PassRefPtr<UStringImpl> singleCharacterSubstring(UStringOrRopeImpl* impl, unsigned index)
+{
+top:
+    if (impl->isRope()) {
+        URopeImpl* rope = static_cast<URopeImpl*>(impl);
+        for (unsigned i = 0; i < rope->m_fiberCount; ++i) {
+            UStringOrRopeImpl* currentFiber = rope->fibers(i);
+            unsigned fiberLength = currentFiber->length();
+            if (index < fiberLength) {
+                impl = currentFiber;
+                goto top;
+            }
+            index -= fiberLength;
+        }
+        CRASH();
+    }
+
+    return static_cast<UStringImpl*>(impl)->singleCharacterSubstring(index);
+}
+
 } // namespace JSC
diff --git a/JavaScriptCore/runtime/UStringImpl.h b/JavaScriptCore/runtime/UStringImpl.h
index 142e01d..718cea4 100644
--- a/JavaScriptCore/runtime/UStringImpl.h
+++ b/JavaScriptCore/runtime/UStringImpl.h
@@ -212,6 +212,8 @@ public:
         ASSERT(!isStatic() || !isIdentifier());
     }
 
+    PassRefPtr<UStringImpl> singleCharacterSubstring(unsigned index) { ASSERT(index < length()); return create(this, index, 1); }
+
 private:
     // For SmallStringStorage, which allocates an array and uses an in-place new.
     UStringImpl() { }
@@ -342,6 +344,7 @@ private:
     Fiber m_fibers[1];
 
     friend class UStringOrRopeImpl;
+    friend PassRefPtr<UStringImpl> singleCharacterSubstring(UStringOrRopeImpl* ropeoid, unsigned index);
 };
 
 inline void UStringOrRopeImpl::deref()
@@ -354,6 +357,8 @@ inline void UStringOrRopeImpl::deref()
 
 bool equal(const UStringImpl*, const UStringImpl*);
 
+PassRefPtr<UStringImpl> singleCharacterSubstring(UStringOrRopeImpl* ropeoid, unsigned index);
+
 }
 
 #endif

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list