js/src/jsapi-tests/testArrayBuffer.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  */
     5 #include "jsfriendapi.h"
     7 #include "jsapi-tests/tests.h"
     9 BEGIN_TEST(testArrayBuffer_bug720949_steal)
    10 {
    11     static const unsigned NUM_TEST_BUFFERS  = 2;
    12     static const unsigned MAGIC_VALUE_1 = 3;
    13     static const unsigned MAGIC_VALUE_2 = 17;
    15     JS::RootedObject buf_len1(cx), buf_len200(cx);
    16     JS::RootedObject tarray_len1(cx), tarray_len200(cx);
    18     uint32_t sizes[NUM_TEST_BUFFERS] = { sizeof(uint32_t), 200 * sizeof(uint32_t) };
    19     JS::HandleObject testBuf[NUM_TEST_BUFFERS] = { buf_len1, buf_len200 };
    20     JS::HandleObject testArray[NUM_TEST_BUFFERS] = { tarray_len1, tarray_len200 };
    22     // Single-element ArrayBuffer (uses fixed slots for storage)
    23     CHECK(buf_len1 = JS_NewArrayBuffer(cx, sizes[0]));
    24     CHECK(tarray_len1 = JS_NewInt32ArrayWithBuffer(cx, testBuf[0], 0, -1));
    26     JS_SetElement(cx, testArray[0], 0, MAGIC_VALUE_1);
    28     // Many-element ArrayBuffer (uses dynamic storage)
    29     CHECK(buf_len200 = JS_NewArrayBuffer(cx, 200 * sizeof(uint32_t)));
    30     CHECK(tarray_len200 = JS_NewInt32ArrayWithBuffer(cx, testBuf[1], 0, -1));
    32     for (unsigned i = 0; i < NUM_TEST_BUFFERS; i++) {
    33         JS::HandleObject obj = testBuf[i];
    34         JS::HandleObject view = testArray[i];
    35         uint32_t size = sizes[i];
    36         JS::RootedValue v(cx);
    38         // Byte lengths should all agree
    39         CHECK(JS_IsArrayBufferObject(obj));
    40         CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), size);
    41         JS_GetProperty(cx, obj, "byteLength", &v);
    42         CHECK_SAME(v, INT_TO_JSVAL(size));
    43         JS_GetProperty(cx, view, "byteLength", &v);
    44         CHECK_SAME(v, INT_TO_JSVAL(size));
    46         // Modifying the underlying data should update the value returned through the view
    47         uint8_t *data = JS_GetStableArrayBufferData(cx, obj);
    48         CHECK(data != nullptr);
    49         *reinterpret_cast<uint32_t*>(data) = MAGIC_VALUE_2;
    50         CHECK(JS_GetElement(cx, view, 0, &v));
    51         CHECK_SAME(v, INT_TO_JSVAL(MAGIC_VALUE_2));
    53         // Steal the contents
    54         void *contents = JS_StealArrayBufferContents(cx, obj);
    55         CHECK(contents != nullptr);
    56         CHECK(data != nullptr);
    58         // Check that the original ArrayBuffer is neutered
    59         CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), 0);
    60         CHECK(JS_GetProperty(cx, obj, "byteLength", &v));
    61         CHECK_SAME(v, INT_TO_JSVAL(0));
    62         CHECK(JS_GetProperty(cx, view, "byteLength", &v));
    63         CHECK_SAME(v, INT_TO_JSVAL(0));
    64         CHECK(JS_GetProperty(cx, view, "byteOffset", &v));
    65         CHECK_SAME(v, INT_TO_JSVAL(0));
    66         CHECK(JS_GetProperty(cx, view, "length", &v));
    67         CHECK_SAME(v, INT_TO_JSVAL(0));
    68         CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), 0);
    69         v = JSVAL_VOID;
    70         JS_GetElement(cx, obj, 0, &v);
    71         CHECK_SAME(v, JSVAL_VOID);
    73         // Transfer to a new ArrayBuffer
    74         JS::RootedObject dst(cx, JS_NewArrayBufferWithContents(cx, size, contents));
    75         CHECK(JS_IsArrayBufferObject(dst));
    76         data = JS_GetStableArrayBufferData(cx, obj);
    78         JS::RootedObject dstview(cx, JS_NewInt32ArrayWithBuffer(cx, dst, 0, -1));
    79         CHECK(dstview != nullptr);
    81         CHECK_EQUAL(JS_GetArrayBufferByteLength(dst), size);
    82         data = JS_GetStableArrayBufferData(cx, dst);
    83         CHECK(data != nullptr);
    84         CHECK_EQUAL(*reinterpret_cast<uint32_t*>(data), MAGIC_VALUE_2);
    85         CHECK(JS_GetElement(cx, dstview, 0, &v));
    86         CHECK_SAME(v, INT_TO_JSVAL(MAGIC_VALUE_2));
    87     }
    89     return true;
    90 }
    91 END_TEST(testArrayBuffer_bug720949_steal)
    93 // Varying number of views of a buffer, to test the neutering weak pointers
    94 BEGIN_TEST(testArrayBuffer_bug720949_viewList)
    95 {
    96     JS::RootedObject buffer(cx);
    98     // No views
    99     buffer = JS_NewArrayBuffer(cx, 2000);
   100     buffer = nullptr;
   101     GC(cx);
   103     // One view.
   104     {
   105         buffer = JS_NewArrayBuffer(cx, 2000);
   106         JS::RootedObject view(cx, JS_NewUint8ArrayWithBuffer(cx, buffer, 0, -1));
   107         void *contents = JS_StealArrayBufferContents(cx, buffer);
   108         CHECK(contents != nullptr);
   109         JS_free(nullptr, contents);
   110         GC(cx);
   111         CHECK(isNeutered(view));
   112         CHECK(isNeutered(buffer));
   113         view = nullptr;
   114         GC(cx);
   115         buffer = nullptr;
   116         GC(cx);
   117     }
   119     // Two views
   120     {
   121         buffer = JS_NewArrayBuffer(cx, 2000);
   123         JS::RootedObject view1(cx, JS_NewUint8ArrayWithBuffer(cx, buffer, 0, -1));
   124         JS::RootedObject view2(cx, JS_NewUint8ArrayWithBuffer(cx, buffer, 1, 200));
   126         // Remove, re-add a view
   127         view2 = nullptr;
   128         GC(cx);
   129         view2 = JS_NewUint8ArrayWithBuffer(cx, buffer, 1, 200);
   131         // Neuter
   132         void *contents = JS_StealArrayBufferContents(cx, buffer);
   133         CHECK(contents != nullptr);
   134         JS_free(nullptr, contents);
   136         CHECK(isNeutered(view1));
   137         CHECK(isNeutered(view2));
   138         CHECK(isNeutered(buffer));
   140         view1 = nullptr;
   141         GC(cx);
   142         view2 = nullptr;
   143         GC(cx);
   144         buffer = nullptr;
   145         GC(cx);
   146     }
   148     return true;
   149 }
   151 static void GC(JSContext *cx)
   152 {
   153     JS_GC(JS_GetRuntime(cx));
   154     JS_GC(JS_GetRuntime(cx)); // Trigger another to wait for background finalization to end
   155 }
   157 bool isNeutered(JS::HandleObject obj) {
   158     JS::RootedValue v(cx);
   159     return JS_GetProperty(cx, obj, "byteLength", &v) && v.toInt32() == 0;
   160 }
   162 END_TEST(testArrayBuffer_bug720949_viewList)

mercurial