Bug 1509168 - Use JS_GetObjectAsArrayBufferView() to retrieve ArrayBufferView data r=asuth
authorviolet <violet.bugreport@gmail.com>
Wed, 17 Apr 2019 12:59:20 +0000
changeset 469866 7f67ed870073a113f9a7a901cb9fe8a70f7ebe72
parent 469865 06e8fe752e305124ac95c939de5aa958190a8e94
child 469867 56329e6eb549344038fc9572be9af64a0af4fcbc
push id35883
push userbtara@mozilla.com
push dateWed, 17 Apr 2019 21:47:29 +0000
treeherdermozilla-central@02b89c29412b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1509168
milestone68.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 1509168 - Use JS_GetObjectAsArrayBufferView() to retrieve ArrayBufferView data r=asuth When using JS_IsArrayBufferViewObject() to check ArrayBufferView object, we should use JS_GetObjectAsArrayBufferView() to get its length and data. Because in rare case there might be a wrapper on the object, JS_GetObjectAsArrayBufferView() will handle it, js::GetArrayBufferViewLengthAndData() won't. Differential Revision: https://phabricator.services.mozilla.com/D24009
dom/indexedDB/Key.cpp
dom/indexedDB/test/chrome.ini
dom/indexedDB/test/test_wrappedArray.xul
--- a/dom/indexedDB/Key.cpp
+++ b/dom/indexedDB/Key.cpp
@@ -628,18 +628,22 @@ double Key::DecodeNumber(const unsigned 
 
 nsresult Key::EncodeBinary(JSObject* aObject, bool aIsViewObject,
                            uint8_t aTypeOffset) {
   uint8_t* bufferData;
   uint32_t bufferLength;
   bool unused;
 
   if (aIsViewObject) {
-    js::GetArrayBufferViewLengthAndData(aObject, &bufferLength, &unused,
-                                        &bufferData);
+    // We must use JS_GetObjectAsArrayBufferView() instead of
+    // js::GetArrayBufferLengthAndData(). Because we check ArrayBufferView
+    // via JS_IsArrayBufferViewObject(), the object might be wrapped,
+    // the former will handle the wrapped case, the later won't.
+    JS_GetObjectAsArrayBufferView(aObject, &bufferLength, &unused, &bufferData);
+
   } else {
     JS::GetArrayBufferLengthAndData(aObject, &bufferLength, &unused,
                                     &bufferData);
   }
 
   return EncodeAsString(bufferData, bufferData + bufferLength,
                         eBinary + aTypeOffset);
 }
--- a/dom/indexedDB/test/chrome.ini
+++ b/dom/indexedDB/test/chrome.ini
@@ -1,4 +1,5 @@
 [DEFAULT]
 support-files = chromeHelpers.js
 
 [test_globalObjects_chrome.xul]
+[test_wrappedArray.xul]
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/test_wrappedArray.xul
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1509168
+-->
+<window title="Mozilla Bug 1509168"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1509168"
+     target="_blank">Mozilla Bug 1509168</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+  function go() {
+    window.iwin = document.getElementById('ifr').contentWindow;
+
+    let evilarr = new iwin.Uint8ClampedArray(3);
+
+    try {
+      window.indexedDB.cmp(evilarr, undefined);
+    } catch (e) {}
+
+    ok(true, "should reach here instead of crash");
+  }
+  ]]>
+  </script>
+  <iframe id="ifr" onload="go();" />
+</window>