Bug 891107 - Part 6: Show information about range and value in array index error messages in js-ctypes. r=jorendorff

This commit is contained in:
Tooru Fujisawa 2015-08-07 06:53:50 +09:00
Родитель 2a08a120e2
Коммит be989eb432
4 изменённых файлов: 82 добавлений и 12 удалений

Просмотреть файл

@ -1494,6 +1494,40 @@ IncompatibleThisType(JSContext* cx, const char* funName, const char* actualType,
return false;
}
static bool
InvalidIndexError(JSContext* cx, HandleValue val)
{
JSAutoByteString idBytes;
const char* indexStr = CTypesToSourceForError(cx, val, idBytes);
if (!indexStr)
return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
CTYPESMSG_INVALID_INDEX, indexStr);
return false;
}
static bool
InvalidIndexError(JSContext* cx, HandleId id)
{
RootedValue idVal(cx, IdToValue(id));
return InvalidIndexError(cx, idVal);
}
static bool
InvalidIndexRangeError(JSContext* cx, size_t index, size_t length)
{
char indexStr[16];
JS_snprintf(indexStr, 16, "%u", index);
char lengthStr[16];
JS_snprintf(lengthStr, 16, "%u", length);
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
CTYPESMSG_INVALID_RANGE, indexStr, lengthStr);
return false;
}
static bool
NonPrimitiveError(JSContext* cx, HandleObject typeObj)
{
@ -5376,9 +5410,11 @@ ArrayType::Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle
// Chances are it's a regular property lookup, so return.
return true;
}
if (!ok || index >= length) {
JS_ReportError(cx, "invalid index");
return false;
if (!ok) {
return InvalidIndexError(cx, idval);
}
if (index >= length) {
return InvalidIndexRangeError(cx, index, length);
}
RootedObject baseType(cx, GetBaseType(typeObj));
@ -5417,9 +5453,11 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle
// Chances are it's a regular property lookup, so return.
return result.succeed();
}
if (!ok || index >= length) {
JS_ReportError(cx, "invalid index");
return false;
if (!ok) {
return InvalidIndexError(cx, idval);
}
if (index >= length) {
return InvalidIndexRangeError(cx, index, length);
}
RootedObject baseType(cx, GetBaseType(typeObj));
@ -5469,10 +5507,11 @@ ArrayType::AddressOfElement(JSContext* cx, unsigned argc, Value* vp)
// Convert the index to a size_t and bounds-check it.
size_t index;
size_t length = GetLength(typeObj);
if (!jsvalToSize(cx, args[0], false, &index) ||
index >= length) {
JS_ReportError(cx, "invalid index");
return false;
if (!jsvalToSize(cx, args[0], false, &index)) {
return InvalidIndexError(cx, args[0]);
}
if (index >= length) {
return InvalidIndexRangeError(cx, index, length);
}
// Manually set the pointer inside the object, so we skip the conversion step.

Просмотреть файл

@ -24,6 +24,8 @@ MSG_DEF(CTYPESMSG_TYPE_ERROR, 2, JSEXN_TYPEERR, "expected {0}, got {1}")
/* array */
MSG_DEF(CTYPESMSG_ARRAY_MISMATCH,4, JSEXN_TYPEERR, "length of {0} does not match to the length of the type {1} (expected {2}, got {3})")
MSG_DEF(CTYPESMSG_ARRAY_OVERFLOW,4, JSEXN_TYPEERR, "length of {0} does not fit in the length of the type {1} (expected {2} or lower, got {3})")
MSG_DEF(CTYPESMSG_INVALID_INDEX, 1, JSEXN_TYPEERR, "{0} is not a valid array index")
MSG_DEF(CTYPESMSG_INVALID_RANGE, 2, JSEXN_RANGEERR, "array index {0} is out of bounds for array of length {1}")
/* struct */
MSG_DEF(CTYPESMSG_FIELD_MISMATCH,5, JSEXN_TYPEERR, "property count of {0} does not match to field count of the type {1} (expected {2}, got {3}){4}")

Просмотреть файл

@ -0,0 +1,29 @@
load(libdir + 'asserts.js');
function test() {
let a = ctypes.int32_t.array(10)();
assertTypeErrorMessage(() => { let x = a[-1]; },
"the string \"-1\" is not a valid array index");
assertTypeErrorMessage(() => { a[-1] = 1; },
"the string \"-1\" is not a valid array index");
assertTypeErrorMessage(() => { a.addressOfElement(-1); },
"the number -1 is not a valid array index");
assertRangeErrorMessage(() => { let x = a[10]; },
"array index 10 is out of bounds for array of length 10");
assertRangeErrorMessage(() => { a[10] = 1; },
"array index 10 is out of bounds for array of length 10");
assertRangeErrorMessage(() => { a.addressOfElement(10); },
"array index 10 is out of bounds for array of length 10");
let obj = {
toSource() {
throw 1;
}
};
assertTypeErrorMessage(() => { a.addressOfElement(obj); },
"<<error converting value to string>> is not a valid array index");
}
if (typeof ctypes === "object")
test();

Просмотреть файл

@ -2016,9 +2016,9 @@ function run_ArrayType_tests() {
a[0] = g;
do_check_eq(a[0].a, 1);
do_check_eq(a[0].b, 2);
do_check_throws(function() { a[-1]; }, Error);
do_check_throws(function() { a[-1]; }, TypeError);
do_check_eq(a[9].a, 0);
do_check_throws(function() { a[10]; }, Error);
do_check_throws(function() { a[10]; }, RangeError);
do_check_eq(a[ctypes.Int64(0)].a, 1);
do_check_eq(a[ctypes.UInt64(0)].b, 2);