Out of bounds getters for Results return undefined

This commit is contained in:
Scott Kyle 2015-10-12 15:35:13 -07:00
parent 6788cd6f3d
commit 35a8f9816c
5 changed files with 18 additions and 14 deletions

View File

@ -66,14 +66,6 @@ static inline ObjectArray * RJSVerifiedMutableArray(JSObjectRef object) {
return array;
}
static inline size_t RJSVerifiedPositiveIndex(std::string indexStr) {
long index = std::stol(indexStr);
if (index < 0) {
throw std::out_of_range(std::string("Index ") + indexStr + " cannot be less than zero.");
}
return index;
}
JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) {
try {
// index subscripting
@ -85,7 +77,7 @@ JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
return JSValueMakeNumber(ctx, size);
}
return RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(RJSVerifiedPositiveIndex(indexStr))));
return RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(RJSValidatedPositiveIndex(indexStr))));
}
catch (std::out_of_range &exp) {
// getters for nonexistent properties in JS should always return undefined
@ -111,7 +103,7 @@ bool ArraySetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef property
throw std::runtime_error("The 'length' property is readonly.");
}
array->set(RJSVerifiedPositiveIndex(indexStr), RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(value), array->object_schema.name, false));
array->set(RJSValidatedPositiveIndex(indexStr), RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(value), array->object_schema.name, false));
return true;
}
catch (std::invalid_argument &exp) {

View File

@ -34,7 +34,11 @@ JSValueRef ResultsGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
return JSValueMakeNumber(ctx, size);
}
return RJSObjectCreate(ctx, Object(results->realm, results->object_schema, results->get(std::stol(indexStr))));
return RJSObjectCreate(ctx, Object(results->realm, results->object_schema, results->get(RJSValidatedPositiveIndex(indexStr))));
}
catch (std::out_of_range &exp) {
// getters for nonexistent properties in JS should always return undefined
return JSValueMakeUndefined(ctx);
}
catch (std::invalid_argument &exp) {
// for stol failure this could be another property that is handled externally, so ignore

View File

@ -179,6 +179,14 @@ static inline size_t RJSValidatedArrayLength(JSContextRef ctx, JSObjectRef objec
return RJSValidatedValueToNumber(ctx, lengthValue);
}
static inline size_t RJSValidatedPositiveIndex(std::string indexStr) {
long index = std::stol(indexStr);
if (index < 0) {
throw std::out_of_range(std::string("Index ") + indexStr + " cannot be less than zero.");
}
return index;
}
static inline bool RJSIsValueObjectOfType(JSContextRef ctx, JSValueRef value, JSStringRef type) {
JSObjectRef globalObject = JSContextGetGlobalObject(ctx);

View File

@ -43,7 +43,7 @@ Row Results::get(std::size_t row_ndx)
{
verify_attached();
if (row_ndx >= table_view.size()) {
throw std::range_error(std::string("Index ") + std::to_string(row_ndx) + " is outside of range 0..." +
throw std::out_of_range(std::string("Index ") + std::to_string(row_ndx) + " is outside of range 0..." +
std::to_string(table_view.size()) + ".");
}
return table_view.get(row_ndx);

View File

@ -40,8 +40,8 @@ var ResultsTests = {
var people = realm.objects('PersonObject');
TestCase.assertEqual(people[0].age, 1);
TestCase.assertEqual(people[1].age, 2);
TestCase.assertThrows(function() { people[2]; }, 'Invalid index');
TestCase.assertThrows(function() { people[-1]; }, 'Invalid index');
TestCase.assertEqual(people[2], undefined);
TestCase.assertEqual(people[-1], undefined);
TestCase.assertTrue(Object.getPrototypeOf(people[0]) === PersonObject.prototype);
},
testResultsInvalidProperty: function() {