Changeset 260489 in webkit


Ignore:
Timestamp:
Apr 21, 2020 7:35:57 PM (4 years ago)
Author:
ysuzuki@apple.com
Message:

Canonicalize JSBigInt generated by structured-cloning by calling rightTrim
https://bugs.webkit.org/show_bug.cgi?id=210816

Reviewed by Keith Miller and Darin Adler.

Source/JavaScriptCore:

  • runtime/JSBigInt.h:

Source/WebCore:

Let's assume that the serialized data is slightly different. JSBigInt's internal representation has various invariants. For example, if JSBigInt is zero, it should have zero length,
and its sign should be false. But there are various ways of representing zero JSBigInt in serialization format. For example, we can set sign = true, length = 0. Current code strongly
assumes that dumped data meets this JSBigInt's internal invariant. This is not good: for example, if we add a new invariant into JSBigInt, already serialized data would not meet this
invariant.
In this patch, we call JSBigInt::rightTrim(VM&) when finishing JSBigInt deserialization. This means that we canonicalize JSBigInt when finishing creation, and this makes this serialization
format free from JSBigInt's internal invariants. This makes JSBigInt serialization/deserialization robust. And we also add lengthInUint64 == 0 path not to call rightTrim when it is zero.
This makes deserialization robust for zero-length & signed corrupted JSBigInt zero.

  • bindings/js/SerializedScriptValue.cpp:

(WebCore::CloneSerializer::dumpBigInt32Data):
(WebCore::CloneDeserializer::readBigInt):

LayoutTests:

Add HeapZero BigInt test.

  • fast/dom/Window/window-postmessage-clone-expected.txt:
  • fast/dom/Window/window-postmessage-clone.html:
  • js/dom/bigint-canonicalization-in-structured-cloning-expected.txt: Added.
  • js/dom/bigint-canonicalization-in-structured-cloning.html: Added.
  • js/dom/script-tests/bigint-canonicalization-in-structured-cloning.js: Added.
  • platform/gtk/fast/dom/Window/window-postmessage-clone-expected.txt:
Location:
trunk
Files:
3 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r260483 r260489  
     12020-04-21  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Canonicalize JSBigInt generated by structured-cloning by calling rightTrim
     4        https://bugs.webkit.org/show_bug.cgi?id=210816
     5
     6        Reviewed by Keith Miller and Darin Adler.
     7
     8        Add HeapZero BigInt test.
     9
     10        * fast/dom/Window/window-postmessage-clone-expected.txt:
     11        * fast/dom/Window/window-postmessage-clone.html:
     12        * js/dom/bigint-canonicalization-in-structured-cloning-expected.txt: Added.
     13        * js/dom/bigint-canonicalization-in-structured-cloning.html: Added.
     14        * js/dom/script-tests/bigint-canonicalization-in-structured-cloning.js: Added.
     15        * platform/gtk/fast/dom/Window/window-postmessage-clone-expected.txt:
     16
    1172020-04-21  Alexey Shvayka  <shvaikalesh@gmail.com>
    218
  • trunk/LayoutTests/fast/dom/Window/window-postmessage-clone-expected.txt

    r260404 r260489  
    1414PASS: eventData is true of type boolean
    1515PASS: eventData is 1 of type string
     16PASS: eventData is 0 of type bigint
    1617PASS: eventData is 0 of type bigint
    1718PASS: eventData is -20 of type bigint
  • trunk/LayoutTests/fast/dom/Window/window-postmessage-clone.html

    r260404 r260489  
    99document.getElementById("description").innerHTML = "Tests that we clone object hierarchies";
    1010
     11globalThis.heapZero = 100000000000000000000000000000000000000000n - 100000000000000000000000000000000000000000n;
    1112tryPostMessage('null');
    1213tryPostMessage('undefined');
     
    1516tryPostMessage('"1"');
    1617tryPostMessage('0n');
     18tryPostMessage('globalThis.heapZero');
    1719tryPostMessage('-20n');
    1820tryPostMessage('4294967295n');
  • trunk/LayoutTests/platform/gtk/fast/dom/Window/window-postmessage-clone-expected.txt

    r260404 r260489  
    1010PASS: eventData is true of type boolean
    1111PASS: eventData is 1 of type string
     12PASS: eventData is 0 of type bigint
    1213PASS: eventData is 0 of type bigint
    1314PASS: eventData is -20 of type bigint
  • trunk/Source/JavaScriptCore/ChangeLog

    r260486 r260489  
     12020-04-21  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Canonicalize JSBigInt generated by structured-cloning by calling rightTrim
     4        https://bugs.webkit.org/show_bug.cgi?id=210816
     5
     6        Reviewed by Keith Miller and Darin Adler.
     7
     8        * runtime/JSBigInt.h:
     9
    1102020-04-21  Peng Liu  <peng.liu6@apple.com>
    211
  • trunk/Source/JavaScriptCore/runtime/JSBigInt.h

    r260358 r260489  
    6060
    6161    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
    62     static JSBigInt* createZero(VM&);
     62    JS_EXPORT_PRIVATE static JSBigInt* createZero(VM&);
    6363    JS_EXPORT_PRIVATE static JSBigInt* tryCreateWithLength(JSGlobalObject*, unsigned length);
    6464    static JSBigInt* createWithLengthUnchecked(VM&, unsigned length);
     
    157157    Digit digit(unsigned);
    158158    void setDigit(unsigned, Digit); // Use only when initializing.
     159    JS_EXPORT_PRIVATE JSBigInt* rightTrim(VM&);
    159160
    160161private:
     
    245246
    246247    static JSBigInt* copy(VM&, JSBigInt* x);
    247     JSBigInt* rightTrim(VM&);
    248248
    249249    void inplaceMultiplyAdd(Digit multiplier, Digit part);
  • trunk/Source/WebCore/ChangeLog

    r260488 r260489  
     12020-04-21  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Canonicalize JSBigInt generated by structured-cloning by calling rightTrim
     4        https://bugs.webkit.org/show_bug.cgi?id=210816
     5
     6        Reviewed by Keith Miller and Darin Adler.
     7
     8        Let's assume that the serialized data is slightly different. JSBigInt's internal representation has various invariants. For example, if JSBigInt is zero, it should have zero length,
     9        and its sign should be false. But there are various ways of representing zero JSBigInt in serialization format. For example, we can set sign = true, length = 0. Current code strongly
     10        assumes that dumped data meets this JSBigInt's internal invariant. This is not good: for example, if we add a new invariant into JSBigInt, already serialized data would not meet this
     11        invariant.
     12        In this patch, we call `JSBigInt::rightTrim(VM&)` when finishing JSBigInt deserialization. This means that we canonicalize JSBigInt when finishing creation, and this makes this serialization
     13        format free from JSBigInt's internal invariants. This makes JSBigInt serialization/deserialization robust. And we also add lengthInUint64 == 0 path not to call rightTrim when it is zero.
     14        This makes deserialization robust for zero-length & signed corrupted JSBigInt zero.
     15
     16        * bindings/js/SerializedScriptValue.cpp:
     17        (WebCore::CloneSerializer::dumpBigInt32Data):
     18        (WebCore::CloneDeserializer::readBigInt):
     19
    1202020-04-21  Peng Liu  <peng.liu6@apple.com>
    221
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp

    r260404 r260489  
    836836        static_assert(sizeof(uint64_t) == sizeof(unsigned long long));
    837837        write(static_cast<uint8_t>(integer < 0));
     838        if (!integer) {
     839            write(static_cast<uint32_t>(0)); // Length-in-uint64_t
     840            return;
     841        }
    838842        write(static_cast<uint32_t>(1)); // Length-in-uint64_t
    839843        int64_t value = static_cast<int64_t>(integer);
     
    29993003        if (!read(lengthInUint64))
    30003004            return JSValue();
     3005
     3006        if (!lengthInUint64) {
     3007#if USE(BIGINT32)
     3008            return JSValue(JSValue::JSBigInt32, 0);
     3009#else
     3010            JSBigInt* bigInt = JSBigInt::createZero(m_lexicalGlobalObject->vm());
     3011            m_gcBuffer.appendWithCrashOnOverflow(bigInt);
     3012            return bigInt;
     3013#endif
     3014        }
     3015
    30013016#if USE(BIGINT32)
    30023017        static_assert(sizeof(JSBigInt::Digit) == sizeof(uint64_t));
     
    30213036            bigInt->setDigit(0, digit64);
    30223037            bigInt->setSign(sign);
     3038            bigInt = bigInt->rightTrim(m_lexicalGlobalObject->vm());
    30233039            m_gcBuffer.appendWithCrashOnOverflow(bigInt);
    30243040            return bigInt;
     
    30563072        }
    30573073        bigInt->setSign(sign);
     3074        bigInt = bigInt->rightTrim(m_lexicalGlobalObject->vm());
    30583075        m_gcBuffer.appendWithCrashOnOverflow(bigInt);
    30593076        return bigInt;
Note: See TracChangeset for help on using the changeset viewer.