mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1080262 - Disallow ctypes from converting array buffers and typed arrays to pointers, except when passed as arguments r=sfink
This commit is contained in:
parent
668c08efc2
commit
d17ce3dbc7
@ -2216,7 +2216,7 @@ ConvertToJS(JSContext* cx,
|
||||
// ctypes.int8_t, UInt8Array to ctypes.uint8_t, etc.
|
||||
bool CanConvertTypedArrayItemTo(JSObject *baseType, JSObject *valObj, JSContext *cx) {
|
||||
TypeCode baseTypeCode = CType::GetTypeCode(baseType);
|
||||
if (baseTypeCode == TYPE_void_t) {
|
||||
if (baseTypeCode == TYPE_void_t || baseTypeCode == TYPE_char) {
|
||||
return true;
|
||||
}
|
||||
TypeCode elementTypeCode;
|
||||
@ -2249,6 +2249,7 @@ bool CanConvertTypedArrayItemTo(JSObject *baseType, JSObject *valObj, JSContext
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return elementTypeCode == baseTypeCode;
|
||||
}
|
||||
|
||||
@ -2451,9 +2452,13 @@ ImplicitConvert(JSContext* cx,
|
||||
}
|
||||
break;
|
||||
} else if (val.isObject() && JS_IsArrayBufferObject(valObj)) {
|
||||
// Convert ArrayBuffer to pointer without any copy. Just as with C
|
||||
// arrays, we make no effort to keep the ArrayBuffer alive. This
|
||||
// functionality will be removed for all but arguments in bug 1080262.
|
||||
// Convert ArrayBuffer to pointer without any copy. This is only valid
|
||||
// when converting an argument to a function call, as it is possible for
|
||||
// the pointer to be invalidated by anything that runs JS code. (It is
|
||||
// invalid to invoke JS code from a ctypes function call.)
|
||||
if (!isArgument) {
|
||||
return TypeError(cx, "arraybuffer pointer", val);
|
||||
}
|
||||
void* ptr;
|
||||
{
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
@ -2464,12 +2469,15 @@ ImplicitConvert(JSContext* cx,
|
||||
}
|
||||
*static_cast<void**>(buffer) = ptr;
|
||||
break;
|
||||
} if (val.isObject() && JS_IsArrayBufferViewObject(valObj)) {
|
||||
// Same as ArrayBuffer, above, though note that this will take the offset
|
||||
// of the view into account.
|
||||
} else if (val.isObject() && JS_IsArrayBufferViewObject(valObj)) {
|
||||
// Same as ArrayBuffer, above, though note that this will take the
|
||||
// offset of the view into account.
|
||||
if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) {
|
||||
return TypeError(cx, "typed array with the appropriate type", val);
|
||||
}
|
||||
if (!isArgument) {
|
||||
return TypeError(cx, "typed array pointer", val);
|
||||
}
|
||||
void* ptr;
|
||||
{
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
|
@ -1753,7 +1753,6 @@ function run_PointerType_tests() {
|
||||
let z = ctypes.int32_t.array(0)().address();
|
||||
do_check_eq(z.contents.length, 0);
|
||||
|
||||
// Check that you can use an ArrayBuffer or a typed array as a pointer
|
||||
let c_arraybuffer = new ArrayBuffer(256);
|
||||
let typed_array_samples =
|
||||
[
|
||||
@ -1766,6 +1765,8 @@ function run_PointerType_tests() {
|
||||
[new Float32Array(c_arraybuffer), ctypes.float32_t],
|
||||
[new Float64Array(c_arraybuffer), ctypes.float64_t]
|
||||
];
|
||||
|
||||
// Check that you can convert ArrayBuffer or typed array to a C array
|
||||
for (let i = 0; i < typed_array_samples.length; ++i) {
|
||||
for (let j = 0; j < typed_array_samples.length; ++j) {
|
||||
let view = typed_array_samples[i][0];
|
||||
@ -1775,31 +1776,11 @@ function run_PointerType_tests() {
|
||||
|
||||
if (i != j) {
|
||||
do_print("Checking that typed array " + (view.constructor.name) +
|
||||
" canNOT be converted to " + item_type + " pointer/array");
|
||||
do_check_throws(function() { item_type.ptr(view); }, TypeError);
|
||||
" can NOT be converted to " + item_type + " array");
|
||||
do_check_throws(function() { array_type(view); }, TypeError);
|
||||
|
||||
} else {
|
||||
do_print("Checking that typed array " + (view.constructor.name) +
|
||||
" can be converted to " + item_type + " pointer/array");
|
||||
// Fill buffer using view
|
||||
for (let k = 0; k < number_of_items; ++k) {
|
||||
view[k] = k;
|
||||
}
|
||||
|
||||
// Convert ArrayBuffer to pointer then array and check contents
|
||||
let c_ptr = item_type.ptr(c_arraybuffer);
|
||||
let c_array = ctypes.cast(c_ptr, array_type.ptr).contents;
|
||||
for (let k = 0; k < number_of_items; ++k) {
|
||||
do_check_eq(c_array[k], view[k]);
|
||||
}
|
||||
|
||||
// Convert view to pointer then array and check contents
|
||||
c_ptr = item_type.ptr(view);
|
||||
c_array = ctypes.cast(c_ptr, array_type.ptr).contents;
|
||||
for (let k = 0; k < number_of_items; ++k) {
|
||||
do_check_eq(c_array[k], view[k]);
|
||||
}
|
||||
" can be converted to " + item_type + " array");
|
||||
|
||||
// Convert ArrayBuffer to array of the right size and check contents
|
||||
c_array = array_type(c_arraybuffer);
|
||||
@ -1827,15 +1808,24 @@ function run_PointerType_tests() {
|
||||
for (let k = 1; k < number_of_items; ++k) {
|
||||
do_check_eq(c_array[k - 1], view[k]);
|
||||
}
|
||||
|
||||
// Convert array to void*
|
||||
ctypes.voidptr_t(c_arraybuffer);
|
||||
|
||||
// Convert view to void*
|
||||
ctypes.voidptr_t(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that you can't use an ArrayBuffer or a typed array as a pointer
|
||||
for (let i = 0; i < typed_array_samples.length; ++i) {
|
||||
for (let j = 0; j < typed_array_samples.length; ++j) {
|
||||
let view = typed_array_samples[i][0];
|
||||
let item_type = typed_array_samples[j][1];
|
||||
|
||||
do_print("Checking that typed array " + (view.constructor.name) +
|
||||
" can NOT be converted to " + item_type + " pointer/array");
|
||||
do_check_throws(function() { item_type.ptr(c_arraybuffer); }, TypeError);
|
||||
do_check_throws(function() { item_type.ptr(view); }, TypeError);
|
||||
do_check_throws(function() { ctypes.voidptr_t(c_arraybuffer); }, TypeError);
|
||||
do_check_throws(function() { ctypes.voidptr_t(view); }, TypeError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function run_FunctionType_tests() {
|
||||
|
Loading…
Reference in New Issue
Block a user