From e3b277d5ccac5b9a5cdcbb292fb04d84d44c7869 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 29 Aug 2016 14:18:31 +0200 Subject: Fix conversion of QByteArray back to String in JavaScript Commit 3b7e2a69f7eb8597c807de39b4de39721e9e2bd2 changed behavior so that QByteArray is converted to the JS ArrayBuffer type, which is a better fit than QVariant. However ArrayBuffer does not have a toString method in the spec, and therefore any previous implicit toString conversion such as when passing to JSON.parse() would fail. To restore compatibility this patch adds a non-spec toString() that performs an UTF-8 conversion, as it was done previously through QVariant's toString. Task-number: QTBUG-55562 Change-Id: I096046954f7b29f7258deaa9ef5c8fa9292552ef Reviewed-by: Lars Knoll Reviewed-by: J-P Nurmi --- src/qml/jsruntime/qv4arraybuffer.cpp | 10 ++++++++++ src/qml/jsruntime/qv4arraybuffer_p.h | 1 + tests/auto/qml/qjsvalue/tst_qjsvalue.cpp | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp index e006773c9e..34c7746684 100644 --- a/src/qml/jsruntime/qv4arraybuffer.cpp +++ b/src/qml/jsruntime/qv4arraybuffer.cpp @@ -154,6 +154,7 @@ void ArrayBufferPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(engine->id_constructor(), (o = ctor)); defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, 0); defineDefaultProperty(QStringLiteral("slice"), method_slice, 2); + defineDefaultProperty(QStringLiteral("toString"), method_toString, 0); } ReturnedValue ArrayBufferPrototype::method_get_byteLength(CallContext *ctx) @@ -198,3 +199,12 @@ ReturnedValue ArrayBufferPrototype::method_slice(CallContext *ctx) return newBuffer.asReturnedValue(); } + +ReturnedValue ArrayBufferPrototype::method_toString(CallContext *ctx) +{ + Scope scope(ctx); + Scoped a(scope, ctx->thisObject()); + if (!a) + return Encode::undefined(); + return Encode(ctx->engine()->newString(QString::fromUtf8(a->asByteArray()))); +} diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h index d079aeb9f7..b552cef9f1 100644 --- a/src/qml/jsruntime/qv4arraybuffer_p.h +++ b/src/qml/jsruntime/qv4arraybuffer_p.h @@ -106,6 +106,7 @@ struct ArrayBufferPrototype: Object static ReturnedValue method_get_byteLength(CallContext *ctx); static ReturnedValue method_slice(CallContext *ctx); + static ReturnedValue method_toString(CallContext *ctx); }; diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index 28b9adea38..d28bbc1ffa 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -431,6 +431,12 @@ void tst_QJSValue::toString() QVERIFY(!o.engine()); QCOMPARE(o.toString(), QStringLiteral("1,2,3")); } + + { + QByteArray hello = QByteArrayLiteral("Hello World"); + QJSValue jsValue = eng.toScriptValue(hello); + QCOMPARE(jsValue.toString(), QString::fromUtf8(hello)); + } } void tst_QJSValue::toNumber() -- cgit v1.2.3