| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index b45f6e3343efd03597ac83d86f49260887203a9f..cb00dff4afa0680ee5517897c7ae2177d09886c4 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -871,6 +871,10 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
|
| ASSERT(args.length() == 2);
|
| CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
|
| CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
|
| + if (!holder->byte_length()->IsUndefined()) {
|
| + // ArrayBuffer is already initialized; probably a fuzz test.
|
| + return *holder;
|
| + }
|
| size_t allocated_length = 0;
|
| if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
|
| return isolate->Throw(
|
| @@ -1055,7 +1059,7 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
|
| CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
|
| CONVERT_SMI_ARG_CHECKED(arrayId, 1);
|
| CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
|
| - CONVERT_ARG_HANDLE_CHECKED(Object, length_obj, 3);
|
| + CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
|
|
|
| ASSERT(holder->GetInternalFieldCount() ==
|
| v8::ArrayBufferView::kInternalFieldCount);
|
| @@ -1079,7 +1083,8 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
|
| JSTypedArray::cast(*source)->type() == array_type) {
|
| length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
|
| }
|
| - size_t length = NumberToSize(isolate, *length_obj);
|
| + size_t length = 0;
|
| + RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
|
|
|
| if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
|
| (length > (kMaxInt / element_size))) {
|
| @@ -1191,17 +1196,17 @@ enum TypedArraySetResultCodes {
|
| RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 3);
|
| - CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
|
| - CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1);
|
| - CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2);
|
| -
|
| - if (!target_obj->IsJSTypedArray())
|
| + if (!args[0]->IsJSTypedArray())
|
| return isolate->Throw(*isolate->factory()->NewTypeError(
|
| "not_typed_array", HandleVector<Object>(NULL, 0)));
|
|
|
| - if (!source_obj->IsJSTypedArray())
|
| + if (!args[1]->IsJSTypedArray())
|
| return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
|
|
|
| + CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
|
| + CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
|
| + CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
|
| +
|
| Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
|
| Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
|
| size_t offset = NumberToSize(isolate, *offset_obj);
|
| @@ -1260,23 +1265,31 @@ RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
|
| ASSERT(args.length() == 4);
|
| CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
|
| CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
|
| - CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2);
|
| - CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3);
|
| + CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
|
| + CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
|
|
|
| ASSERT(holder->GetInternalFieldCount() ==
|
| v8::ArrayBufferView::kInternalFieldCount);
|
| for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
|
| holder->SetInternalField(i, Smi::FromInt(0));
|
| }
|
| + size_t buffer_length = 0;
|
| + size_t offset = 0;
|
| + size_t length = 0;
|
| + RUNTIME_ASSERT(
|
| + TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
|
| + RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
|
| + RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
|
| +
|
| + // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
|
| + // Entire range [offset, offset + length] must be in bounds.
|
| + RUNTIME_ASSERT(offset <= buffer_length);
|
| + RUNTIME_ASSERT(offset + length <= buffer_length);
|
| + // No overflow.
|
| + RUNTIME_ASSERT(offset + length >= offset);
|
|
|
| holder->set_buffer(*buffer);
|
| - ASSERT(byte_offset->IsNumber());
|
| - ASSERT(
|
| - NumberToSize(isolate, buffer->byte_length()) >=
|
| - NumberToSize(isolate, *byte_offset)
|
| - + NumberToSize(isolate, *byte_length));
|
| holder->set_byte_offset(*byte_offset);
|
| - ASSERT(byte_length->IsNumber());
|
| holder->set_byte_length(*byte_length);
|
|
|
| holder->set_weak_next(buffer->weak_first_view());
|
| @@ -1582,8 +1595,8 @@ RUNTIME_FUNCTION(Runtime_SetCreateIterator) {
|
| ASSERT(args.length() == 2);
|
| CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
|
| CONVERT_SMI_ARG_CHECKED(kind, 1)
|
| - ASSERT(kind == JSSetIterator::kKindValues
|
| - || kind == JSSetIterator::kKindEntries);
|
| + RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
|
| + kind == JSSetIterator::kKindEntries);
|
| Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
|
| return *JSSetIterator::Create(table, kind);
|
| }
|
| @@ -3097,11 +3110,8 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
|
| ASSERT(args.length() == 2);
|
|
|
| CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
|
| - CONVERT_ARG_HANDLE_CHECKED(Object, code, 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
|
|
|
| - if (code->IsNull()) return *target;
|
| - RUNTIME_ASSERT(code->IsJSFunction());
|
| - Handle<JSFunction> source = Handle<JSFunction>::cast(code);
|
| Handle<SharedFunctionInfo> target_shared(target->shared());
|
| Handle<SharedFunctionInfo> source_shared(source->shared());
|
|
|
| @@ -4296,7 +4306,7 @@ RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
|
| CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
|
| CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
|
|
|
| - ASSERT(regexp->GetFlags().is_global());
|
| + RUNTIME_ASSERT(regexp->GetFlags().is_global());
|
|
|
| subject = String::Flatten(subject);
|
|
|
| @@ -7231,6 +7241,12 @@ RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
|
| CONVERT_SMI_ARG_CHECKED(array_length, 1);
|
| CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
|
|
|
| + size_t actual_array_length = 0;
|
| + RUNTIME_ASSERT(
|
| + TryNumberToSize(isolate, array->length(), &actual_array_length));
|
| + RUNTIME_ASSERT(array_length >= 0);
|
| + RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
|
| +
|
| // This assumption is used by the slice encoding in one or two smis.
|
| ASSERT(Smi::kMaxValue >= String::kMaxLength);
|
|
|
| @@ -7599,7 +7615,8 @@ RUNTIME_FUNCTION(Runtime_NumberCompare) {
|
|
|
| CONVERT_DOUBLE_ARG_CHECKED(x, 0);
|
| CONVERT_DOUBLE_ARG_CHECKED(y, 1);
|
| - if (std::isnan(x) || std::isnan(y)) return args[2];
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
|
| + if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
|
| if (x == y) return Smi::FromInt(EQUAL);
|
| if (isless(x, y)) return Smi::FromInt(LESS);
|
| return Smi::FromInt(GREATER);
|
| @@ -7887,15 +7904,15 @@ RUNTIME_FUNCTION(RuntimeHidden_MathPow) {
|
| RUNTIME_FUNCTION(Runtime_RoundNumber) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 1);
|
| + CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
|
| isolate->counters()->math_round()->Increment();
|
|
|
| - if (!args[0]->IsHeapNumber()) {
|
| - // Must be smi. Return the argument unchanged for all the other types
|
| - // to make fuzz-natives test happy.
|
| - return args[0];
|
| + if (!input->IsHeapNumber()) {
|
| + ASSERT(input->IsSmi());
|
| + return *input;
|
| }
|
|
|
| - HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]);
|
| + Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
|
|
|
| double value = number->value();
|
| int exponent = number->get_exponent();
|
| @@ -7917,7 +7934,7 @@ RUNTIME_FUNCTION(Runtime_RoundNumber) {
|
| // If the magnitude is big enough, there's no place for fraction part. If we
|
| // try to add 0.5 to this number, 1.0 will be added instead.
|
| if (exponent >= 52) {
|
| - return number;
|
| + return *number;
|
| }
|
|
|
| if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
|
| @@ -9666,22 +9683,22 @@ RUNTIME_FUNCTION(Runtime_DateParseString) {
|
|
|
| JSObject::EnsureCanContainHeapObjectElements(output);
|
| RUNTIME_ASSERT(output->HasFastObjectElements());
|
| + Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
|
| + RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
|
|
|
| str = String::Flatten(str);
|
| DisallowHeapAllocation no_gc;
|
|
|
| - FixedArray* output_array = FixedArray::cast(output->elements());
|
| - RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
|
| bool result;
|
| String::FlatContent str_content = str->GetFlatContent();
|
| if (str_content.IsAscii()) {
|
| result = DateParser::Parse(str_content.ToOneByteVector(),
|
| - output_array,
|
| + *output_array,
|
| isolate->unicode_cache());
|
| } else {
|
| ASSERT(str_content.IsTwoByte());
|
| result = DateParser::Parse(str_content.ToUC16Vector(),
|
| - output_array,
|
| + *output_array,
|
| isolate->unicode_cache());
|
| }
|
|
|
| @@ -13473,6 +13490,9 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
|
| CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
|
| CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
|
| CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
|
| + RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
|
| + RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
|
| + RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
|
|
|
| LiveEdit::ReplaceRefToNestedFunction(
|
| parent_wrapper, orig_wrapper, subst_wrapper);
|
| @@ -14547,6 +14567,8 @@ RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
|
| if (idx < 0) {
|
| idx = -idx + object->map()->inobject_properties() - 1;
|
| }
|
| + Handle<Object> raw_value(object->RawFastPropertyAt(idx), isolate);
|
| + RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized());
|
| return *JSObject::FastPropertyAt(object, Representation::Double(), idx);
|
| }
|
|
|
| @@ -14892,7 +14914,7 @@ RUNTIME_FUNCTION(Runtime_IsAccessAllowedForObserver) {
|
| ASSERT(args.length() == 3);
|
| CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
|
| CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
|
| - ASSERT(object->map()->is_access_check_needed());
|
| + RUNTIME_ASSERT(object->map()->is_access_check_needed());
|
| CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
|
| SaveContext save(isolate);
|
| isolate->set_context(observer->context());
|
|
|