Skip to content
This repository has been archived by the owner on Oct 15, 2020. It is now read-only.

Commit

Permalink
chakrashim: fix index/toInteger int overflow
Browse files Browse the repository at this point in the history
Fix JsIntToNumber calls which may overflow when casting to int.

Reviewed-by: @kunalspathak
  • Loading branch information
Jianchun Xu committed Sep 5, 2015
1 parent 56dc0bb commit 47477f6
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 43 deletions.
38 changes: 24 additions & 14 deletions deps/chakrashim/src/jsrtutils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@

namespace jsrt {

JsErrorCode UintToValue(uint32_t value, JsValueRef* result) {
if (static_cast<int>(value) >= 0) {
return JsIntToNumber(static_cast<int>(value), result);
}

// Otherwise doesn't fit int, use double
return JsDoubleToNumber(value, result);
}

JsErrorCode GetProperty(JsValueRef ref,
JsValueRef propName,
JsValueRef *result) {
Expand Down Expand Up @@ -274,10 +283,10 @@ JsErrorCode HasOwnProperty(JsValueRef object,
}

JsErrorCode IsValueInArray(
JsValueRef arrayRef,
JsValueRef valueRef,
std::function<JsErrorCode(JsValueRef, JsValueRef, bool*)> comperator,
bool* result) {
JsValueRef arrayRef,
JsValueRef valueRef,
std::function<JsErrorCode(JsValueRef, JsValueRef, bool*)> comparator,
bool* result) {
JsErrorCode error;
unsigned int length;
*result = false;
Expand All @@ -299,8 +308,8 @@ JsErrorCode IsValueInArray(
return error;
}

if (comperator != nullptr) {
error = comperator(valueRef, itemRef, result);
if (comparator != nullptr) {
error = comparator(valueRef, itemRef, result);
} else {
error = JsEquals(itemRef, valueRef, result);
}
Expand Down Expand Up @@ -750,11 +759,11 @@ JsErrorCode GetObjectConstructor(JsValueRef objectRef,
}

JsErrorCode SetIndexedProperty(JsValueRef object,
int index,
unsigned int index,
JsValueRef value) {
JsErrorCode error;
JsValueRef indexRef;
error = JsIntToNumber(index, &indexRef);
error = UintToValue(index, &indexRef);
if (error != JsNoError) {
return error;
}
Expand All @@ -764,11 +773,11 @@ JsErrorCode SetIndexedProperty(JsValueRef object,
}

JsErrorCode GetIndexedProperty(JsValueRef object,
int index,
unsigned int index,
JsValueRef *value) {
JsErrorCode error;
JsValueRef indexRef;
error = JsIntToNumber(index, &indexRef);
error = UintToValue(index, &indexRef);
if (error != JsNoError) {
return error;
}
Expand All @@ -778,10 +787,10 @@ JsErrorCode GetIndexedProperty(JsValueRef object,
}

JsErrorCode DeleteIndexedProperty(JsValueRef object,
int index) {
unsigned int index) {
JsErrorCode error;
JsValueRef indexRef;
error = JsIntToNumber(index, &indexRef);
error = UintToValue(index, &indexRef);
if (error != JsNoError) {
return error;
}
Expand All @@ -807,18 +816,19 @@ JsErrorCode HasProperty(JsValueRef object,
}

JsErrorCode HasIndexedProperty(JsValueRef object,
int index,
unsigned int index,
bool *result) {
JsErrorCode error;
JsValueRef indexRef;
error = JsIntToNumber(index, &indexRef);
error = UintToValue(index, &indexRef);
if (error != JsNoError) {
return error;
}

error = JsHasIndexedProperty(object, indexRef, result);
return error;
}

JsErrorCode ParseScript(const wchar_t *script,
JsSourceContext sourceContext,
const wchar_t *sourceUrl,
Expand Down
10 changes: 6 additions & 4 deletions deps/chakrashim/src/jsrtutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ namespace jsrt {

JsErrorCode InitializePromise();

JsErrorCode UintToValue(uint32_t value, JsValueRef* result);

JsErrorCode GetProperty(JsValueRef ref,
JsValueRef propName,
JsValueRef *result);
Expand All @@ -80,7 +82,7 @@ JsErrorCode SetProperty(JsValueRef ref,
JsValueRef propValue);

JsErrorCode DeleteIndexedProperty(JsValueRef object,
int index);
unsigned int index);

JsErrorCode DeleteProperty(JsValueRef ref,
JsValueRef propName,
Expand Down Expand Up @@ -119,7 +121,7 @@ JsErrorCode HasProperty(JsValueRef object,
bool *result);

JsErrorCode HasIndexedProperty(JsValueRef object,
int index,
unsigned int index,
bool *result);

JsErrorCode GetEnumerableNamedProperties(JsValueRef object,
Expand Down Expand Up @@ -267,11 +269,11 @@ JsErrorCode GetObjectConstructor(JsValueRef objectRef,
JsValueRef *constructorRef);

JsErrorCode SetIndexedProperty(JsValueRef object,
int index,
unsigned int index,
JsValueRef value);

JsErrorCode GetIndexedProperty(JsValueRef object,
int index,
unsigned int index,
JsValueRef *value);

// CHAKRA-TODO : Currently Chakra's ParseScript doesn't support strictMode
Expand Down
10 changes: 6 additions & 4 deletions deps/chakrashim/src/v8integer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ Local<Integer> Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
}

Local<Integer> Integer::From(uint32_t value) {
if (static_cast<int32_t>(value) >= 0) {
return From(static_cast<int32_t>(value));
JsValueRef ref;

if (jsrt::UintToValue(value, &ref) != JsNoError) {
return Local<Integer>();
}

// Otherwise doesn't fit in int32, use double
return Number::From(value).As<Integer>();
// For perf reason, this doesn't allocate a real Handle
return Local<Integer>(ref);
}

Integer* Integer::Cast(v8::Value* obj) {
Expand Down
18 changes: 2 additions & 16 deletions deps/chakrashim/src/v8object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,8 @@ bool Object::ForceSet(Handle<Value> key, Handle<Value> value,
}

MaybeLocal<Value> Object::Get(Local<Context> context, Local<Value> key) {
JsPropertyIdRef idRef;

if (GetPropertyIdFromValue((JsValueRef)*key, &idRef) != JsNoError) {
return Local<Value>();
}

JsValueRef valueRef;
if (JsGetProperty((JsValueRef)this, idRef, &valueRef) != JsNoError) {
if (jsrt::GetProperty((JsValueRef)this, *key, &valueRef) != JsNoError) {
return Local<Value>();
}

Expand Down Expand Up @@ -253,19 +247,11 @@ bool Object::Has(Handle<Value> key) {
}

Maybe<bool> Object::Delete(Local<Context> context, Local<Value> key) {
JsPropertyIdRef idRef;

if (GetPropertyIdFromName((JsValueRef)*key, &idRef) != JsNoError) {
return Nothing<bool>();
}

JsValueRef resultRef;
if (JsDeleteProperty((JsValueRef)this,
idRef, false, &resultRef) != JsNoError) {
if (jsrt::DeleteProperty(this, *key, &resultRef) != JsNoError) {
return Nothing<bool>();
}

// get result
return Just(Local<Value>(resultRef)->BooleanValue());
}

Expand Down
12 changes: 7 additions & 5 deletions deps/chakrashim/src/v8value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,15 @@ MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
return Local<Integer>();
}

JsValueRef integerRef;
if (JsIntToNumber(static_cast<int>(maybeValue.FromJust()),
&integerRef) != JsNoError) {
return Local<Integer>();
int64_t value = maybeValue.FromJust();
int intValue = static_cast<int>(value);

if (value == static_cast<int64_t>(intValue)) {
return Integer::New(nullptr, intValue);
}

return Local<Integer>::New(integerRef);
// does not fit int, use double
return Number::New(nullptr, value).As<Integer>();
}

MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
Expand Down

0 comments on commit 47477f6

Please sign in to comment.