Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: src/json-stringifier.h

Issue 1996333002: [json] handle access checks in BasicJsonStringifier. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@jsonstringifier
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/js/json.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_JSON_STRINGIFIER_H_ 5 #ifndef V8_JSON_STRINGIFIER_H_
6 #define V8_JSON_STRINGIFIER_H_ 6 #define V8_JSON_STRINGIFIER_H_
7 7
8 #include "src/conversions.h" 8 #include "src/conversions.h"
9 #include "src/lookup.h" 9 #include "src/lookup.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 15 matching lines...) Expand all
26 Isolate* isolate, 26 Isolate* isolate,
27 Handle<String> object)); 27 Handle<String> object));
28 28
29 private: 29 private:
30 enum Result { UNCHANGED, SUCCESS, EXCEPTION }; 30 enum Result { UNCHANGED, SUCCESS, EXCEPTION };
31 31
32 MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction( 32 MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction(
33 Handle<Object> object, 33 Handle<Object> object,
34 Handle<Object> key); 34 Handle<Object> key);
35 35
36 Result SerializeGeneric(Handle<Object> object,
37 Handle<Object> key,
38 bool deferred_comma,
39 bool deferred_key);
40
41 // Entry point to serialize the object. 36 // Entry point to serialize the object.
42 INLINE(Result SerializeObject(Handle<Object> obj)) { 37 INLINE(Result SerializeObject(Handle<Object> obj)) {
43 return Serialize_<false>(obj, false, factory()->empty_string()); 38 return Serialize_<false>(obj, false, factory()->empty_string());
44 } 39 }
45 40
46 // Serialize an array element. 41 // Serialize an array element.
47 // The index may serve as argument for the toJSON function. 42 // The index may serve as argument for the toJSON function.
48 INLINE(Result SerializeElement(Isolate* isolate, 43 INLINE(Result SerializeElement(Isolate* isolate,
49 Handle<Object> object, 44 Handle<Object> object,
50 int i)) { 45 int i)) {
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 builder_.AppendCString("true"); 351 builder_.AppendCString("true");
357 return SUCCESS; 352 return SUCCESS;
358 case Oddball::kNull: 353 case Oddball::kNull:
359 if (deferred_string_key) SerializeDeferredKey(comma, key); 354 if (deferred_string_key) SerializeDeferredKey(comma, key);
360 builder_.AppendCString("null"); 355 builder_.AppendCString("null");
361 return SUCCESS; 356 return SUCCESS;
362 default: 357 default:
363 return UNCHANGED; 358 return UNCHANGED;
364 } 359 }
365 case JS_ARRAY_TYPE: 360 case JS_ARRAY_TYPE:
366 if (object->IsAccessCheckNeeded()) break;
367 if (deferred_string_key) SerializeDeferredKey(comma, key); 361 if (deferred_string_key) SerializeDeferredKey(comma, key);
368 return SerializeJSArray(Handle<JSArray>::cast(object)); 362 return SerializeJSArray(Handle<JSArray>::cast(object));
369 case JS_VALUE_TYPE: 363 case JS_VALUE_TYPE:
370 if (deferred_string_key) SerializeDeferredKey(comma, key); 364 if (deferred_string_key) SerializeDeferredKey(comma, key);
371 return SerializeJSValue(Handle<JSValue>::cast(object)); 365 return SerializeJSValue(Handle<JSValue>::cast(object));
366 case SIMD128_VALUE_TYPE:
367 case SYMBOL_TYPE:
368 return UNCHANGED;
372 default: 369 default:
373 if (object->IsString()) { 370 if (object->IsString()) {
374 if (deferred_string_key) SerializeDeferredKey(comma, key); 371 if (deferred_string_key) SerializeDeferredKey(comma, key);
375 SerializeString(Handle<String>::cast(object)); 372 SerializeString(Handle<String>::cast(object));
376 return SUCCESS; 373 return SUCCESS;
377 } else if (object->IsJSReceiver()) { 374 } else {
375 DCHECK(object->IsJSReceiver());
378 if (object->IsCallable()) return UNCHANGED; 376 if (object->IsCallable()) return UNCHANGED;
379 // Go to slow path for global proxy and objects requiring access checks. 377 // Go to slow path for global proxy and objects requiring access checks.
380 if (object->IsAccessCheckNeeded() || object->IsJSGlobalProxy()) break;
381 if (deferred_string_key) SerializeDeferredKey(comma, key); 378 if (deferred_string_key) SerializeDeferredKey(comma, key);
382 if (object->IsJSProxy()) { 379 if (object->IsJSProxy()) {
383 return SerializeJSProxy(Handle<JSProxy>::cast(object)); 380 return SerializeJSProxy(Handle<JSProxy>::cast(object));
384 } 381 }
385 return SerializeJSObject(Handle<JSObject>::cast(object)); 382 return SerializeJSObject(Handle<JSObject>::cast(object));
386 } 383 }
387 } 384 }
388 385
389 return SerializeGeneric(object, key, comma, deferred_string_key); 386 UNREACHABLE();
387 return UNCHANGED;
390 } 388 }
391 389
392 390
393 BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric(
394 Handle<Object> object,
395 Handle<Object> key,
396 bool deferred_comma,
397 bool deferred_key) {
398 Handle<JSFunction> fun = isolate_->json_serialize_adapter();
399 Handle<Object> indent(Smi::FromInt(indent_), isolate_);
400 Handle<Object> argv[] = {key, object, indent, gap_string_};
401 Handle<Object> result;
402 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
403 isolate_, result,
404 Execution::Call(isolate_, fun, object, arraysize(argv), argv), EXCEPTION);
405 if (result->IsUndefined()) return UNCHANGED;
406 if (deferred_key) {
407 if (key->IsSmi()) key = factory()->NumberToString(key);
408 SerializeDeferredKey(deferred_comma, key);
409 }
410
411 builder_.AppendString(Handle<String>::cast(result));
412 return SUCCESS;
413 }
414
415
416 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue( 391 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue(
417 Handle<JSValue> object) { 392 Handle<JSValue> object) {
418 String* class_name = object->class_name(); 393 String* class_name = object->class_name();
419 if (class_name == isolate_->heap()->String_string()) { 394 if (class_name == isolate_->heap()->String_string()) {
420 Handle<Object> value; 395 Handle<Object> value;
421 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 396 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
422 isolate_, value, Object::ToString(isolate_, object), EXCEPTION); 397 isolate_, value, Object::ToString(isolate_, object), EXCEPTION);
423 SerializeString(Handle<String>::cast(value)); 398 SerializeString(Handle<String>::cast(value));
424 } else if (class_name == isolate_->heap()->Number_string()) { 399 } else if (class_name == isolate_->heap()->Number_string()) {
425 Handle<Object> value; 400 Handle<Object> value;
426 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, value, Object::ToNumber(object), 401 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, value, Object::ToNumber(object),
427 EXCEPTION); 402 EXCEPTION);
428 if (value->IsSmi()) return SerializeSmi(Smi::cast(*value)); 403 if (value->IsSmi()) return SerializeSmi(Smi::cast(*value));
429 SerializeHeapNumber(Handle<HeapNumber>::cast(value)); 404 SerializeHeapNumber(Handle<HeapNumber>::cast(value));
430 } else if (class_name == isolate_->heap()->Boolean_string()) { 405 } else if (class_name == isolate_->heap()->Boolean_string()) {
431 Object* value = JSValue::cast(*object)->value(); 406 Object* value = JSValue::cast(*object)->value();
432 DCHECK(value->IsBoolean()); 407 DCHECK(value->IsBoolean());
433 builder_.AppendCString(value->IsTrue() ? "true" : "false"); 408 builder_.AppendCString(value->IsTrue() ? "true" : "false");
434 } else { 409 } else {
435 // ES6 24.3.2.1 step 10.c, serialize as an ordinary JSObject. 410 // ES6 24.3.2.1 step 10.c, serialize as an ordinary JSObject.
436 CHECK(!object->IsAccessCheckNeeded());
437 CHECK(!object->IsJSGlobalProxy());
438 return SerializeJSObject(object); 411 return SerializeJSObject(object);
439 } 412 }
440 return SUCCESS; 413 return SUCCESS;
441 } 414 }
442 415
443 416
444 BasicJsonStringifier::Result BasicJsonStringifier::SerializeSmi(Smi* object) { 417 BasicJsonStringifier::Result BasicJsonStringifier::SerializeSmi(Smi* object) {
445 static const int kBufferSize = 100; 418 static const int kBufferSize = 100;
446 char chars[kBufferSize]; 419 char chars[kBufferSize];
447 Vector<char> buffer(chars, kBufferSize); 420 Vector<char> buffer(chars, kBufferSize);
(...skipping 16 matching lines...) Expand all
464 } 437 }
465 438
466 439
467 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( 440 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray(
468 Handle<JSArray> object) { 441 Handle<JSArray> object) {
469 HandleScope handle_scope(isolate_); 442 HandleScope handle_scope(isolate_);
470 Result stack_push = StackPush(object); 443 Result stack_push = StackPush(object);
471 if (stack_push != SUCCESS) return stack_push; 444 if (stack_push != SUCCESS) return stack_push;
472 uint32_t length = 0; 445 uint32_t length = 0;
473 CHECK(object->length()->ToArrayLength(&length)); 446 CHECK(object->length()->ToArrayLength(&length));
447 DCHECK(!object->IsAccessCheckNeeded());
474 builder_.AppendCharacter('['); 448 builder_.AppendCharacter('[');
475 Indent(); 449 Indent();
476 switch (object->GetElementsKind()) { 450 switch (object->GetElementsKind()) {
477 case FAST_SMI_ELEMENTS: { 451 case FAST_SMI_ELEMENTS: {
478 Handle<FixedArray> elements(FixedArray::cast(object->elements()), 452 Handle<FixedArray> elements(FixedArray::cast(object->elements()),
479 isolate_); 453 isolate_);
480 for (uint32_t i = 0; i < length; i++) { 454 for (uint32_t i = 0; i < length; i++) {
481 Separator(i == 0); 455 Separator(i == 0);
482 SerializeSmi(Smi::cast(elements->get(i))); 456 SerializeSmi(Smi::cast(elements->get(i)));
483 } 457 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 } 528 }
555 } 529 }
556 return SUCCESS; 530 return SUCCESS;
557 } 531 }
558 532
559 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( 533 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
560 Handle<JSObject> object) { 534 Handle<JSObject> object) {
561 HandleScope handle_scope(isolate_); 535 HandleScope handle_scope(isolate_);
562 Result stack_push = StackPush(object); 536 Result stack_push = StackPush(object);
563 if (stack_push != SUCCESS) return stack_push; 537 if (stack_push != SUCCESS) return stack_push;
564 DCHECK(!object->IsJSGlobalProxy() && !object->IsJSGlobalObject());
565 538
566 if (object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER && 539 if (object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER &&
567 object->HasFastProperties() && 540 object->HasFastProperties() &&
568 Handle<JSObject>::cast(object)->elements()->length() == 0) { 541 Handle<JSObject>::cast(object)->elements()->length() == 0) {
569 DCHECK(object->IsJSObject()); 542 DCHECK(object->IsJSObject());
543 DCHECK(!object->IsJSGlobalProxy());
570 Handle<JSObject> js_obj = Handle<JSObject>::cast(object); 544 Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
571 DCHECK(!js_obj->HasIndexedInterceptor()); 545 DCHECK(!js_obj->HasIndexedInterceptor());
572 DCHECK(!js_obj->HasNamedInterceptor()); 546 DCHECK(!js_obj->HasNamedInterceptor());
573 Handle<Map> map(js_obj->map()); 547 Handle<Map> map(js_obj->map());
574 builder_.AppendCharacter('{'); 548 builder_.AppendCharacter('{');
575 Indent(); 549 Indent();
576 bool comma = false; 550 bool comma = false;
577 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { 551 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
578 Handle<Name> name(map->instance_descriptors()->GetKey(i), isolate_); 552 Handle<Name> name(map->instance_descriptors()->GetKey(i), isolate_);
579 // TODO(rossberg): Should this throw? 553 // TODO(rossberg): Should this throw?
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } else { 741 } else {
768 SerializeString_<uc16, uc16>(object); 742 SerializeString_<uc16, uc16>(object);
769 } 743 }
770 } 744 }
771 } 745 }
772 746
773 } // namespace internal 747 } // namespace internal
774 } // namespace v8 748 } // namespace v8
775 749
776 #endif // V8_JSON_STRINGIFIER_H_ 750 #endif // V8_JSON_STRINGIFIER_H_
OLDNEW
« no previous file with comments | « src/js/json.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698