aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/v8/qv8jsonwrapper.cpp
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-08-16 14:11:52 +0200
committerQt by Nokia <qt-info@nokia.com>2012-08-20 13:24:31 +0200
commitcd6eabb2d68321536c7fbc032a2a93990e891936 (patch)
tree9f3ed5952f5da0da1ed3ee4959f891fcad9d4d42 /src/qml/qml/v8/qv8jsonwrapper.cpp
parent2791a13757912cfd0d5cc6a83f228fab5c1645ae (diff)
Use object identity to detect cycles in JS-to-C++ type conversion
The documentation for v8::Object::GetIdentityHash() states that the hash value is not guaranteed to be unique (the current implementation just returns a random number). Hence, the hash value should not be used to determine whether an object has already been visited during type conversion; in the worst (and non-deterministic) case, the conversion will be "cut off" prematurely (due to identical hash values for two different objects), resulting in data loss. Instead, represent the visited objects as a set of V8 object handles. This is safe since the type conversion is always done on the stack, within a handle scope. Use v8::Object::GetIdentityHash() merely to implement the qHash() specialization needed for the set. V8 already provides an operator==() for handles, and it is documented to return true "if the objects to which they refer are identical", which is the behavior required by the set implementation. Task-number: QTBUG-21681 Change-Id: I1f2a1eee8f7c197c02c2ffeaaa1fc0274e8ab740 Reviewed-by: Michael Brasser <michael.brasser@nokia.com> Reviewed-by: Simon Hausmann <simon.hausmann@nokia.com>
Diffstat (limited to 'src/qml/qml/v8/qv8jsonwrapper.cpp')
-rw-r--r--src/qml/qml/v8/qv8jsonwrapper.cpp20
1 files changed, 9 insertions, 11 deletions
diff --git a/src/qml/qml/v8/qv8jsonwrapper.cpp b/src/qml/qml/v8/qv8jsonwrapper.cpp
index ff8b69f580..5ba59b2263 100644
--- a/src/qml/qml/v8/qv8jsonwrapper.cpp
+++ b/src/qml/qml/v8/qv8jsonwrapper.cpp
@@ -82,7 +82,7 @@ v8::Handle<v8::Value> QV8JsonWrapper::fromJsonValue(const QJsonValue &value)
}
QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value,
- QSet<int> &visitedObjects)
+ V8ObjectSet &visitedObjects)
{
if (value->IsString())
return QJsonValue(QJSConverter::toString(value.As<v8::String>()));
@@ -109,22 +109,21 @@ v8::Local<v8::Object> QV8JsonWrapper::fromJsonObject(const QJsonObject &object)
}
QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value,
- QSet<int> &visitedObjects)
+ V8ObjectSet &visitedObjects)
{
QJsonObject result;
if (!value->IsObject() || value->IsArray() || value->IsFunction())
return result;
v8::Handle<v8::Object> v8object(value.As<v8::Object>());
- int hash = v8object->GetIdentityHash();
- if (visitedObjects.contains(hash)) {
+ if (visitedObjects.contains(v8object)) {
// Avoid recursion.
// For compatibility with QVariant{List,Map} conversion, we return an
// empty object (and no error is thrown).
return result;
}
- visitedObjects.insert(hash);
+ visitedObjects.insert(v8object);
v8::Local<v8::Array> propertyNames = m_engine->getOwnPropertyNames(v8object);
uint32_t length = propertyNames->Length();
@@ -136,7 +135,7 @@ QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value,
toJsonValue(propertyValue, visitedObjects));
}
- visitedObjects.remove(hash);
+ visitedObjects.remove(v8object);
return result;
}
@@ -151,22 +150,21 @@ v8::Local<v8::Array> QV8JsonWrapper::fromJsonArray(const QJsonArray &array)
}
QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value,
- QSet<int> &visitedObjects)
+ V8ObjectSet &visitedObjects)
{
QJsonArray result;
if (!value->IsArray())
return result;
v8::Handle<v8::Array> v8array(value.As<v8::Array>());
- int hash = v8array->GetIdentityHash();
- if (visitedObjects.contains(hash)) {
+ if (visitedObjects.contains(v8array)) {
// Avoid recursion.
// For compatibility with QVariant{List,Map} conversion, we return an
// empty array (and no error is thrown).
return result;
}
- visitedObjects.insert(hash);
+ visitedObjects.insert(v8array);
uint32_t length = v8array->Length();
for (uint32_t i = 0; i < length; ++i) {
@@ -175,7 +173,7 @@ QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value,
result.append(toJsonValue(element, visitedObjects));
}
- visitedObjects.remove(hash);
+ visitedObjects.remove(v8array);
return result;
}