aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4jsonobject.cpp
diff options
context:
space:
mode:
authorIvan Tkachenko <me@ratijas.tk>2023-02-20 03:30:37 +0300
committerIvan Tkachenko <me@ratijas.tk>2023-02-22 18:21:09 +0300
commit4c930247e67ecad383aa7e8d9a3308b38629bef8 (patch)
tree4aca9540a12fbd01f7a57db1232bef562134d8e2 /src/qml/jsruntime/qv4jsonobject.cpp
parentc769e1a8db9a5762bb80cbc34473ec48a670a038 (diff)
Set correct `this` value in JSON.stringify replacer scope
Long story short, JSON.stringify takes optional second argument which can be a replacer function. It is supposed to be called for each encountered key-value during serialization. While replacer's second argument is already serialized (so you could just return it), just in case you are not satisfied with default serialization — the original value is still passed in together with the whole object as a value of JavaScript `this`. Sadly, there is no test in the whole ECMA test suite to catch this bug. This is quite a breaking change for code which already uses Qt-specific workarounds, so it would be better not to cherry-pick it as a hot-fix onto existing (released) branches. Sample use case: serialize dates as a number of seconds since epoch. function replacer(k, v) { if (this[k] instanceof Date) { return Math.floor(this[k].getTime() / 1000.0); } return v; } const str = JSON.stringify(obj, replacer); [ChangeLog][QML][Important Behavior Changes] Set correct `this` value in JSON.stringify replacer scope, so that the value for current key in current object is no longer pre-stringified, and can actually be used to implement custom object serialization logic. Fixes: QTBUG-95324 Pick-to: 6.5 Change-Id: I618a533e8eba7999d5416aca14f4971093a83f7a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4jsonobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 4f46e605af..7bf7cda02f 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -695,12 +695,18 @@ QString Stringify::Str(const QString &key, const Value &v)
}
if (replacerFunction) {
- ScopedObject holder(scope, v4->newObject());
- holder->put(scope.engine->id_empty(), value);
JSCallArguments jsCallData(scope, 2);
jsCallData.args[0] = v4->newString(key);
jsCallData.args[1] = value;
- *jsCallData.thisObject = holder;
+
+ if (stack.isEmpty()) {
+ ScopedObject holder(scope, v4->newObject());
+ holder->put(scope.engine->id_empty(), v);
+ *jsCallData.thisObject = holder;
+ } else {
+ *jsCallData.thisObject = stack.top();
+ }
+
value = replacerFunction->call(jsCallData);
if (v4->hasException)
return QString();