Commit 1b65970e authored by eric@webkit.org's avatar eric@webkit.org

2010-06-14 Andreas Kling <andreas.kling@nokia.com>

        Reviewed by Tor Arne Vestbø.

        [Qt] Stack overflow when converting navigator object to QVariant
        https://bugs.webkit.org/show_bug.cgi?id=40572

        Protect against infinite recursion in JSValue->QVariant conversion.
        This fixes a crash when trying to convert MimeType objects (they
        recurse infinitely and on-the-fly via the enabledPlugin property.)

        * bridge/qt/qt_runtime.cpp:
        (JSC::Bindings::convertValueToQVariant):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@61127 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c2e395ce
2010-06-14 Andreas Kling <andreas.kling@nokia.com>
Reviewed by Tor Arne Vestbø.
[Qt] Stack overflow when converting navigator object to QVariant
https://bugs.webkit.org/show_bug.cgi?id=40572
Protect against infinite recursion in JSValue->QVariant conversion.
This fixes a crash when trying to convert MimeType objects (they
recurse infinitely and on-the-fly via the enabledPlugin property.)
* bridge/qt/qt_runtime.cpp:
(JSC::Bindings::convertValueToQVariant):
2010-06-14 Yong Li <yoli@rim.com>
Test cases created by: Robin Cao <robin.cao@torchmobile.com.cn>
......
......@@ -162,9 +162,11 @@ static JSRealType valueRealType(ExecState* exec, JSValue val)
return String; // I don't know.
}
QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance, HashSet<JSObject*>* visitedObjects)
QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance, HashSet<JSObject*>* visitedObjects, int recursionLimit)
{
if (!value)
--recursionLimit;
if (!value || !recursionLimit)
return QVariant();
JSObject* object = 0;
......@@ -344,7 +346,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
while(it != properties.end()) {
if (object->propertyIsEnumerable(exec, *it)) {
JSValue val = object->get(exec, *it);
QVariant v = convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects);
QVariant v = convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects, recursionLimit);
if (objdist >= 0) {
UString ustring = (*it).ustring();
QString id = QString((const QChar*)ustring.rep()->characters(), ustring.size());
......@@ -368,7 +370,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
qConvDebug() << "converting a " << len << " length Array";
for (int i = 0; i < len; ++i) {
JSValue val = rtarray->getConcreteArray()->valueAt(exec, i);
result.append(convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects));
result.append(convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects, recursionLimit));
if (objdist == -1) {
qConvDebug() << "Failed converting element at index " << i;
break; // Failed converting a list entry, so fail the array
......@@ -387,7 +389,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
qConvDebug() << "converting a " << len << " length Array";
for (int i = 0; i < len; ++i) {
JSValue val = array->get(exec, i);
result.append(convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects));
result.append(convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects, recursionLimit));
if (objdist == -1) {
qConvDebug() << "Failed converting element at index " << i;
break; // Failed converting a list entry, so fail the array
......@@ -401,7 +403,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
// Make a single length array
int objdist;
qConvDebug() << "making a single length variantlist";
QVariant var = convertValueToQVariant(exec, value, QMetaType::Void, &objdist, visitedObjects);
QVariant var = convertValueToQVariant(exec, value, QMetaType::Void, &objdist, visitedObjects, recursionLimit);
if (objdist != -1) {
QVariantList result;
result << var;
......@@ -645,7 +647,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
for (int i = 0; i < len; ++i) {
JSValue val = rtarray->getConcreteArray()->valueAt(exec, i);
int itemdist = -1;
QVariant item = convertValueToQVariant(exec, val, QMetaType::QObjectStar, &itemdist, visitedObjects);
QVariant item = convertValueToQVariant(exec, val, QMetaType::QObjectStar, &itemdist, visitedObjects, recursionLimit);
if (itemdist >= 0)
result.append(item.value<QObject*>());
else
......@@ -664,7 +666,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
for (int i = 0; i < len; ++i) {
JSValue val = array->get(exec, i);
int itemdist = -1;
QVariant item = convertValueToQVariant(exec, val, QMetaType::QObjectStar, &itemdist, visitedObjects);
QVariant item = convertValueToQVariant(exec, val, QMetaType::QObjectStar, &itemdist, visitedObjects, recursionLimit);
if (itemdist >= 0)
result.append(item.value<QObject*>());
else
......@@ -679,7 +681,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
// Make a single length array
QObjectList result;
int itemdist = -1;
QVariant item = convertValueToQVariant(exec, value, QMetaType::QObjectStar, &itemdist, visitedObjects);
QVariant item = convertValueToQVariant(exec, value, QMetaType::QObjectStar, &itemdist, visitedObjects, recursionLimit);
if (itemdist >= 0) {
result.append(item.value<QObject*>());
dist = 10;
......@@ -696,7 +698,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
for (int i = 0; i < len; ++i) {
JSValue val = rtarray->getConcreteArray()->valueAt(exec, i);
int itemdist = -1;
QVariant item = convertValueToQVariant(exec, val, QMetaType::Int, &itemdist, visitedObjects);
QVariant item = convertValueToQVariant(exec, val, QMetaType::Int, &itemdist, visitedObjects, recursionLimit);
if (itemdist >= 0)
result.append(item.value<int>());
else
......@@ -715,7 +717,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
for (int i = 0; i < len; ++i) {
JSValue val = array->get(exec, i);
int itemdist = -1;
QVariant item = convertValueToQVariant(exec, val, QMetaType::Int, &itemdist, visitedObjects);
QVariant item = convertValueToQVariant(exec, val, QMetaType::Int, &itemdist, visitedObjects, recursionLimit);
if (itemdist >= 0)
result.append(item.value<int>());
else
......@@ -730,7 +732,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
// Make a single length array
QList<int> result;
int itemdist = -1;
QVariant item = convertValueToQVariant(exec, value, QMetaType::Int, &itemdist, visitedObjects);
QVariant item = convertValueToQVariant(exec, value, QMetaType::Int, &itemdist, visitedObjects, recursionLimit);
if (itemdist >= 0) {
result.append(item.value<int>());
dist = 10;
......@@ -757,7 +759,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
}
// And then recurse with the autodetect flag
ret = convertValueToQVariant(exec, value, QMetaType::Void, distance, visitedObjects);
ret = convertValueToQVariant(exec, value, QMetaType::Void, distance, visitedObjects, recursionLimit);
dist = 10;
}
break;
......@@ -777,8 +779,9 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type hint, int *distance)
{
const int recursionLimit = 200;
HashSet<JSObject*> visitedObjects;
return convertValueToQVariant(exec, value, hint, distance, &visitedObjects);
return convertValueToQVariant(exec, value, hint, distance, &visitedObjects, recursionLimit);
}
JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& variant)
......
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