diff --git a/dom/bindings/test/mochitest.ini b/dom/bindings/test/mochitest.ini
index 1b6e49aae9f..4ea9b07893f 100644
--- a/dom/bindings/test/mochitest.ini
+++ b/dom/bindings/test/mochitest.ini
@@ -58,3 +58,4 @@ skip-if = debug == false
[test_promise_rejections_from_jsimplemented.html]
skip-if = debug == false
[test_worker_UnwrapArg.html]
+[test_crossOriginWindowSymbolAccess.html]
diff --git a/dom/bindings/test/test_crossOriginWindowSymbolAccess.html b/dom/bindings/test/test_crossOriginWindowSymbolAccess.html
new file mode 100644
index 00000000000..7808631b6bd
--- /dev/null
+++ b/dom/bindings/test/test_crossOriginWindowSymbolAccess.html
@@ -0,0 +1,23 @@
+
+
+
Test for accessing symbols on a cross-origin window
+
+
+
+
+
diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp
index f347248bc75..cebfc38cf34 100644
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -1749,7 +1749,8 @@ ReportPropertyError(JSContext *cx,
const unsigned errorNumber,
HandleId id)
{
- RootedString str(cx, IdToString(cx, id));
+ RootedValue idVal(cx, IdToValue(id));
+ RootedString str(cx, ValueToSource(cx, idVal));
if (!str)
return false;
diff --git a/js/src/js.msg b/js/src/js.msg
index 5810ac0c7dc..96c55c95bf2 100644
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -142,7 +142,7 @@ MSG_DEF(JSMSG_CSP_BLOCKED_EVAL, 0, JSEXN_ERR, "call to eval() blocked by
MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION, 0, JSEXN_ERR, "call to Function() blocked by CSP")
// Wrappers
-MSG_DEF(JSMSG_ACCESSOR_DEF_DENIED, 1, JSEXN_ERR, "Permission denied to define accessor property '{0}'")
+MSG_DEF(JSMSG_ACCESSOR_DEF_DENIED, 1, JSEXN_ERR, "Permission denied to define accessor property {0}")
MSG_DEF(JSMSG_DEAD_OBJECT, 0, JSEXN_TYPEERR, "can't access dead object")
MSG_DEF(JSMSG_UNWRAP_DENIED, 0, JSEXN_ERR, "permission denied to unwrap object")
@@ -346,7 +346,7 @@ MSG_DEF(JSMSG_INVALID_TRAP_RESULT, 2, JSEXN_TYPEERR, "trap {1} for {0} retur
MSG_DEF(JSMSG_MUST_REPORT_SAME_VALUE, 0, JSEXN_TYPEERR, "proxy must report the same value for a non-writable, non-configurable property")
MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED, 0, JSEXN_TYPEERR, "proxy must report undefined for a non-configurable accessor property without a getter")
MSG_DEF(JSMSG_OBJECT_ACCESS_DENIED, 0, JSEXN_ERR, "Permission denied to access object")
-MSG_DEF(JSMSG_PROPERTY_ACCESS_DENIED, 1, JSEXN_ERR, "Permission denied to access property '{0}'")
+MSG_DEF(JSMSG_PROPERTY_ACCESS_DENIED, 1, JSEXN_ERR, "Permission denied to access property {0}")
MSG_DEF(JSMSG_PROXY_CONSTRUCT_OBJECT, 0, JSEXN_TYPEERR, "proxy [[Construct]] must return an object")
MSG_DEF(JSMSG_PROXY_EXTENSIBILITY, 0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target")
MSG_DEF(JSMSG_PROXY_GETOWN_OBJORUNDEF, 0, JSEXN_TYPEERR, "proxy [[GetOwnProperty]] must return an object or undefined")
diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp
index 1856adb5688..e01c499f801 100644
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -411,7 +411,8 @@ js::Throw(JSContext *cx, jsid id, unsigned errorNumber)
{
MOZ_ASSERT(js_ErrorFormatString[errorNumber].argCount == 1);
- JSString *idstr = IdToString(cx, id);
+ RootedValue idVal(cx, IdToValue(id));
+ JSString *idstr = ValueToSource(cx, idVal);
if (!idstr)
return false;
JSAutoByteString bytes(cx, idstr);
diff --git a/js/src/proxy/Proxy.cpp b/js/src/proxy/Proxy.cpp
index a3416276562..de427243cf3 100644
--- a/js/src/proxy/Proxy.cpp
+++ b/js/src/proxy/Proxy.cpp
@@ -38,7 +38,11 @@ js::AutoEnterPolicy::reportErrorIfExceptionIsNotPending(JSContext *cx, jsid id)
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
JSMSG_OBJECT_ACCESS_DENIED);
} else {
- JSString *str = IdToString(cx, id);
+ RootedValue idVal(cx, IdToValue(id));
+ JSString *str = ValueToSource(cx, idVal);
+ if (!str) {
+ return;
+ }
AutoStableStringChars chars(cx);
const char16_t *prop = nullptr;
if (str->ensureFlat(cx) && chars.initTwoByte(cx, str))
diff --git a/js/src/proxy/SecurityWrapper.cpp b/js/src/proxy/SecurityWrapper.cpp
index 3a739bd4b3a..361121f59f1 100644
--- a/js/src/proxy/SecurityWrapper.cpp
+++ b/js/src/proxy/SecurityWrapper.cpp
@@ -108,7 +108,10 @@ SecurityWrapper::defineProperty(JSContext *cx, HandleObject wrapper,
HandleId id, MutableHandle desc) const
{
if (desc.getter() || desc.setter()) {
- JSString *str = IdToString(cx, id);
+ RootedValue idVal(cx, IdToValue(id));
+ JSString *str = ValueToSource(cx, idVal);
+ if (!str)
+ return false;
AutoStableStringChars chars(cx);
const char16_t *prop = nullptr;
if (str->ensureFlat(cx) && chars.initTwoByte(cx, str))