Bug 1527900 - Throw exception if StructuredClone sees bigint in realm without bigint r=jandem
authorAndy Wingo <wingo@igalia.com>
Fri, 01 Mar 2019 10:01:33 +0000
changeset 519852 e262ebb0128221118ab884f3eecc7ba3f05f2440
parent 519851 dcfebc36f75c8950280cee02cf82398932db98ee
child 519853 666070099fbabe3160da0b468dde6b9130f71262
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1527900
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1527900 - Throw exception if StructuredClone sees bigint in realm without bigint r=jandem Differential Revision: https://phabricator.services.mozilla.com/D21206
js/src/js.msg
js/src/shell/fuzz-flags.txt
js/src/shell/js.cpp
js/src/tests/non262/extensions/clone-bigint.js
js/src/vm/StructuredClone.cpp
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -683,11 +683,12 @@ MSG_DEF(JSMSG_RESPONSE_ALREADY_CONSUMED,
 MSG_DEF(JSMSG_BIGINT_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert BigInt to number")
 MSG_DEF(JSMSG_NUMBER_TO_BIGINT, 0, JSEXN_RANGEERR, "can't convert non-finite number to BigInt")
 MSG_DEF(JSMSG_BIGINT_TOO_LARGE, 0, JSEXN_RANGEERR, "BigInt is too large to allocate")
 MSG_DEF(JSMSG_BIGINT_DIVISION_BY_ZERO, 0, JSEXN_RANGEERR, "BigInt division by zero")
 MSG_DEF(JSMSG_BIGINT_NEGATIVE_EXPONENT, 0, JSEXN_RANGEERR, "BigInt negative exponent")
 MSG_DEF(JSMSG_BIGINT_INVALID_SYNTAX, 0, JSEXN_SYNTAXERR, "invalid BigInt syntax")
 MSG_DEF(JSMSG_NOT_BIGINT, 0, JSEXN_TYPEERR, "not a BigInt")
 MSG_DEF(JSMSG_BIGINT_NOT_SERIALIZABLE, 0, JSEXN_TYPEERR, "BigInt value can't be serialized in JSON")
+MSG_DEF(JSMSG_SC_BIGINT_DISABLED, 0, JSEXN_ERR, "BigInt not cloned - feature disabled in receiver")
 
 // BinAST
 MSG_DEF(JSMSG_BINAST,                                    1, JSEXN_SYNTAXERR, "BinAST Parsing Error: {0}")
--- a/js/src/shell/fuzz-flags.txt
+++ b/js/src/shell/fuzz-flags.txt
@@ -38,16 +38,19 @@
 --ion-warmup-threshold=100
 --no-native-regexp
 --nursery-strings=off
 --nursery-strings=on
 --spectre-mitigations=off
 --spectre-mitigations=on
 --more-compartments
 
+# Experimental JS language features
+--no-bigint
+
 # GC-related
 # These 2 flags can cause the shell to slow down
 # --gc-zeal=2
 # --gc-zeal=10
 --no-cgc
 --no-ggc
 --no-incremental-gc
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -6164,16 +6164,23 @@ static bool NewGlobal(JSContext* cx, uns
 
     if (!JS_GetProperty(cx, opts, "disableLazyParsing", &v)) {
       return false;
     }
     if (v.isBoolean()) {
       behaviors.setDisableLazyParsing(v.toBoolean());
     }
 
+    if (!JS_GetProperty(cx, opts, "enableBigInt", &v)) {
+      return false;
+    }
+    if (v.isBoolean()) {
+      creationOptions.setBigIntEnabled(v.toBoolean());
+    }
+
     if (!JS_GetProperty(cx, opts, "systemPrincipal", &v)) {
       return false;
     }
     if (v.isBoolean()) {
       principals = &ShellPrincipals::fullyTrusted;
       JS_HoldPrincipals(principals);
     }
 
new file mode 100644
--- /dev/null
+++ b/js/src/tests/non262/extensions/clone-bigint.js
@@ -0,0 +1,29 @@
+// |reftest| skip-if(!xulRuntime.shell)
+// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+function testBigInt(b) {
+    var a = deserialize(serialize(b));
+    assertEq(typeof b, "bigint");
+    assertEq(typeof a, "bigint");
+    assertEq(a, b);
+}
+
+testBigInt(0n);
+testBigInt(-1n);
+testBigInt(1n);
+
+testBigInt(0xffffFFFFffffFFFFffffFFFFffffFFFFn);
+testBigInt(-0xffffFFFFffffFFFFffffFFFFffffFFFFn);
+
+var g = newGlobal({ enableBigInt: false, sameCompartmentAs: this });
+var deserializeNoBigInt = g.evaluate("deserialize");
+
+assertEq(deserializeNoBigInt(serialize(1)), 1);
+assertThrows(() => deserializeNoBigInt(serialize(1n)))
+assertThrows(() => deserializeNoBigInt(serialize(0n)))
+assertThrows(() => deserializeNoBigInt(serialize(0xffffffn)))
+assertThrows(() => deserializeNoBigInt(serialize(-1n)))
+
+reportCompare(0, 0, 'ok');
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -2038,16 +2038,22 @@ JSString* JSStructuredCloneReader::readS
 JSString* JSStructuredCloneReader::readString(uint32_t data) {
   uint32_t nchars = data & JS_BITMASK(31);
   bool latin1 = data & (1 << 31);
   return latin1 ? readStringImpl<Latin1Char>(nchars)
                 : readStringImpl<char16_t>(nchars);
 }
 
 BigInt* JSStructuredCloneReader::readBigInt(uint32_t data) {
+  if (!context()->realm()->creationOptions().getBigIntEnabled()) {
+    JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
+                              JSMSG_SC_BIGINT_DISABLED);
+    return nullptr;
+  }
+
   size_t length = data & JS_BITMASK(31);
   bool isNegative = data & (1 << 31);
   if (length == 0) {
     return BigInt::zero(context());
   }
   RootedBigInt result(
       context(), BigInt::createUninitialized(context(), length, isNegative));
   if (!result) {