Commit 9f6d7a00 authored by barraclough@apple.com's avatar barraclough@apple.com

https://bugs.webkit.org/show_bug.cgi?id=35070

Addition of 2 strings of length 2^31 may result in a string of length 0.

Reviewed by Oliver Hunt.

Check for overflow when creating a new JSString as a result of an addition
or concatenation, throw an out of memory exception.

* runtime/JSString.h:
(JSC::):
* runtime/Operations.h:
(JSC::jsString):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54925 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 0f0871cb
2010-02-17 Gavin Barraclough <barraclough@apple.com>
Reviewed by Oliver Hunt.
https://bugs.webkit.org/show_bug.cgi?id=35070
Addition of 2 strings of length 2^31 may result in a string of length 0.
Check for overflow when creating a new JSString as a result of an addition
or concatenation, throw an out of memory exception.
* runtime/JSString.h:
(JSC::):
* runtime/Operations.h:
(JSC::jsString):
2010-02-17 Xan Lopez <xlopez@igalia.com>
Reviewed by Gustavo Noronha.
......
......@@ -104,6 +104,8 @@ namespace JSC {
return m_rope.release();
}
unsigned length() { return m_rope->length(); }
private:
unsigned m_index;
RefPtr<Rope> m_rope;
......
......@@ -37,10 +37,14 @@ namespace JSC {
ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
{
if (!s1->length())
unsigned length1 = s1->length();
if (!length1)
return s2;
if (!s2->length())
unsigned length2 = s2->length();
if (!length2)
return s1;
if ((length1 + length2) < length1)
return throwOutOfMemoryError(exec);
unsigned fiberCount = s1->fiberCount() + s2->fiberCount();
JSGlobalData* globalData = &exec->globalData();
......@@ -58,6 +62,15 @@ namespace JSC {
ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2)
{
unsigned length1 = u1.size();
if (!length1)
return s2;
unsigned length2 = s2->length();
if (!length2)
return jsString(exec, u1);
if ((length1 + length2) < length1)
return throwOutOfMemoryError(exec);
unsigned fiberCount = 1 + s2->fiberCount();
JSGlobalData* globalData = &exec->globalData();
......@@ -74,6 +87,15 @@ namespace JSC {
ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2)
{
unsigned length1 = s1->length();
if (!length1)
return jsString(exec, u2);
unsigned length2 = u2.size();
if (!length2)
return s1;
if ((length1 + length2) < length1)
return throwOutOfMemoryError(exec);
unsigned fiberCount = s1->fiberCount() + 1;
JSGlobalData* globalData = &exec->globalData();
......@@ -109,14 +131,25 @@ namespace JSC {
if (UNLIKELY(ropeBuilder.isOutOfMemory()))
return throwOutOfMemoryError(exec);
unsigned length = 0;
bool overflow = false;
for (unsigned i = 0; i < count; ++i) {
JSValue v = strings[i].jsValue();
if (LIKELY(v.isString()))
ropeBuilder.append(asString(v));
else
ropeBuilder.append(v.toString(exec));
unsigned newLength = ropeBuilder.length();
if (newLength < length)
overflow = true;
length = newLength;
}
if (overflow)
return throwOutOfMemoryError(exec);
return new (globalData) JSString(globalData, ropeBuilder.release());
}
......@@ -143,14 +176,26 @@ namespace JSC {
ropeBuilder.append(asString(thisValue));
else
ropeBuilder.append(thisValue.toString(exec));
unsigned length = 0;
bool overflow = false;
for (unsigned i = 0; i < args.size(); ++i) {
JSValue v = args.at(i);
if (LIKELY(v.isString()))
ropeBuilder.append(asString(v));
else
ropeBuilder.append(v.toString(exec));
unsigned newLength = ropeBuilder.length();
if (newLength < length)
overflow = true;
length = newLength;
}
if (overflow)
return throwOutOfMemoryError(exec);
JSGlobalData* globalData = &exec->globalData();
return new (globalData) JSString(globalData, ropeBuilder.release());
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment