Skip to content
Permalink
Browse files
https://bugs.webkit.org/show_bug.cgi?id=35843
Re-land reverted fix to JSString::getIndex()

Reviewed by Sam Weinig.

Calling getIndex() on a JSString in rope form may result in a JSException being thrown
if there is insuficient memory so value(exec) returns UString() with length zero,
which will be passed to jsSingleCharacterSubstring.
Add a slow case function to trap the error & return a safe null value, until the
exception is handled.

* runtime/JSString.cpp:
(JSC::JSString::getIndexSlowCase):
(JSC::JSString::getStringPropertyDescriptor):
* runtime/JSString.h:
(JSC::jsSingleCharacterSubstring):
(JSC::JSString::getIndex):
(JSC::jsSingleCharacterString):
(JSC::JSString::getStringPropertySlot):



Canonical link: https://commits.webkit.org/47316@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@56021 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Gavin Barraclough committed Mar 15, 2010
1 parent ddf53cd commit f1ee9f021b7b0429605334ae76c37824a8f0c207
Showing 3 changed files with 44 additions and 7 deletions.
@@ -1,3 +1,25 @@
2010-03-15 Gavin Barraclough <barraclough@apple.com>

Reviewed by Sam Weinig.

https://bugs.webkit.org/show_bug.cgi?id=35843
Re-land reverted fix to JSString::getIndex()

Calling getIndex() on a JSString in rope form may result in a JSException being thrown
if there is insuficient memory so value(exec) returns UString() with length zero,
which will be passed to jsSingleCharacterSubstring.
Add a slow case function to trap the error & return a safe null value, until the
exception is handled.

* runtime/JSString.cpp:
(JSC::JSString::getIndexSlowCase):
(JSC::JSString::getStringPropertyDescriptor):
* runtime/JSString.h:
(JSC::jsSingleCharacterSubstring):
(JSC::JSString::getIndex):
(JSC::jsSingleCharacterString):
(JSC::JSString::getStringPropertySlot):

2010-03-04 Kenneth Rohde Christiansen <kenneth@webkit.org>

Reviewed by Adam Roben.
@@ -104,6 +104,18 @@ void JSString::resolveRope(ExecState* exec) const
}
}

JSString* JSString::getIndexSlowCase(ExecState* exec, unsigned i)
{
ASSERT(isRope());
resolveRope(exec);
// Return a safe no-value result, this should never be used, since the excetion will be thrown.
if (exec->exception())
return jsString(exec, "");
ASSERT(!isRope());
ASSERT(i < m_value.size());
return jsSingleCharacterSubstring(exec, m_value, i);
}

JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
return const_cast<JSString*>(this);
@@ -187,7 +199,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;
}

@@ -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);
@@ -240,6 +239,7 @@ namespace JSC {

bool canGetIndex(unsigned i) { return i < m_length; }
JSString* getIndex(ExecState*, unsigned);
JSString* getIndexSlowCase(ExecState*, unsigned);

static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); }

@@ -365,8 +365,9 @@ 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,10 @@ namespace JSC {
inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
{
ASSERT(canGetIndex(i));
return jsSingleCharacterSubstring(&exec->globalData(), value(exec), i);
if (isRope())
return getIndexSlowCase(exec, i);
ASSERT(i < m_value.size());
return jsSingleCharacterSubstring(exec, value(exec), i);
}

inline JSString* jsString(JSGlobalData* globalData, const UString& s)
@@ -445,7 +449,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 +464,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 +474,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;
}

0 comments on commit f1ee9f0

Please sign in to comment.