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:
Jon Coppeard 2014-11-03 11:38:12 -08:00
parent 668c08efc2
commit d17ce3dbc7
2 changed files with 34 additions and 36 deletions

View File

@ -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;

View File

@ -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() {