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

Side by Side Diff: src/object-observe.js

Issue 265503002: Re-enable Object.observe and add enforcement for security invariants. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: cleanup Created 6 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 | Annotate | Revision Log
« no previous file with comments | « src/api.cc ('k') | src/objects.h » ('j') | src/runtime.cc » ('J')
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 "use strict"; 5 "use strict";
6 6
7 // Overview: 7 // Overview:
8 // 8 //
9 // This file contains all of the routing and accounting for Object.observe. 9 // This file contains all of the routing and accounting for Object.observe.
10 // User code will interact with these mechanisms via the Object.observe APIs 10 // User code will interact with these mechanisms via the Object.observe APIs
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 } 393 }
394 394
395 function ObserverEnqueueIfActive(observer, objectInfo, changeRecord, 395 function ObserverEnqueueIfActive(observer, objectInfo, changeRecord,
396 needsAccessCheck) { 396 needsAccessCheck) {
397 if (!ObserverIsActive(observer, objectInfo) || 397 if (!ObserverIsActive(observer, objectInfo) ||
398 !TypeMapHasType(ObserverGetAcceptTypes(observer), changeRecord.type)) { 398 !TypeMapHasType(ObserverGetAcceptTypes(observer), changeRecord.type)) {
399 return; 399 return;
400 } 400 }
401 401
402 var callback = ObserverGetCallback(observer); 402 var callback = ObserverGetCallback(observer);
403 if (needsAccessCheck && 403 if (needsAccessCheck && !%IsAccessAllowedForObserver(callback,
404 // Drop all splice records on the floor for access-checked objects 404 changeRecord.object,
405 (changeRecord.type == 'splice' || 405 changeRecord)) {
406 !%IsAccessAllowedForObserver(
407 callback, changeRecord.object, changeRecord.name))) {
408 return; 406 return;
409 } 407 }
410 408
411 var callbackInfo = CallbackInfoNormalize(callback); 409 var callbackInfo = CallbackInfoNormalize(callback);
412 if (IS_NULL(GetPendingObservers())) { 410 if (IS_NULL(GetPendingObservers())) {
413 SetPendingObservers(nullProtoObject()) 411 SetPendingObservers(nullProtoObject())
414 GetMicrotaskQueue().push(ObserveMicrotaskRunner); 412 GetMicrotaskQueue().push(ObserveMicrotaskRunner);
415 %SetMicrotaskPending(true); 413 %SetMicrotaskPending(true);
416 } 414 }
417 GetPendingObservers()[callbackInfo.priority] = callback; 415 GetPendingObservers()[callbackInfo.priority] = callback;
418 callbackInfo.push(changeRecord); 416 callbackInfo.push(changeRecord);
419 } 417 }
420 418
421 function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) { 419 function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
422 if (!ObjectInfoHasActiveObservers(objectInfo)) 420 if (!ObjectInfoHasActiveObservers(objectInfo))
423 return; 421 return;
424 422
425 var hasType = !IS_UNDEFINED(type); 423 var hasType = !IS_UNDEFINED(type);
426 var newRecord = hasType ? 424 var newRecord = hasType ?
427 { object: ObjectInfoGetObject(objectInfo), type: type } : 425 { object: ObjectInfoGetObject(objectInfo), type: type } :
428 { object: ObjectInfoGetObject(objectInfo) }; 426 { object: ObjectInfoGetObject(objectInfo) };
429 427
430 for (var prop in changeRecord) { 428 for (var prop in changeRecord) {
431 if (prop === 'object' || (hasType && prop === 'type')) continue; 429 if (prop === 'object' || (hasType && prop === 'type')) continue;
432 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop], 430 %DefineOrRedefineDataProperty(newRecord, prop, changeRecord[prop],
433 READ_ONLY + DONT_DELETE); 431 READ_ONLY + DONT_DELETE);
434 } 432 }
435 ObjectFreeze(newRecord); 433 ObjectFreeze(newRecord);
436 434
437 ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord, 435 ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord);
438 true /* skip access check */);
439 } 436 }
440 437
441 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord, 438 function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) {
442 skipAccessCheck) {
443 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 439 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
444 if (IS_SYMBOL(changeRecord.name)) return; 440 if (IS_SYMBOL(changeRecord.name)) return;
445 441
446 var needsAccessCheck = !skipAccessCheck && 442 var needsAccessCheck = %IsAccessCheckNeeded(changeRecord.object);
rossberg 2014/04/30 11:28:32 I believe you always need to do the same-origin ch
rafaelw 2014/05/02 03:22:32 Done.
447 %IsAccessCheckNeeded(changeRecord.object);
448 443
449 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) { 444 if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
450 var observer = objectInfo.changeObservers; 445 var observer = objectInfo.changeObservers;
451 ObserverEnqueueIfActive(observer, objectInfo, changeRecord, 446 ObserverEnqueueIfActive(observer, objectInfo, changeRecord,
452 needsAccessCheck); 447 needsAccessCheck);
453 return; 448 return;
454 } 449 }
455 450
456 for (var priority in objectInfo.changeObservers) { 451 for (var priority in objectInfo.changeObservers) {
457 var observer = objectInfo.changeObservers[priority]; 452 var observer = objectInfo.changeObservers[priority];
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 if (IS_SPEC_OBJECT(changeRecord)) 550 if (IS_SPEC_OBJECT(changeRecord))
556 ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType); 551 ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType);
557 } 552 }
558 553
559 function ObjectGetNotifier(object) { 554 function ObjectGetNotifier(object) {
560 if (!IS_SPEC_OBJECT(object)) 555 if (!IS_SPEC_OBJECT(object))
561 throw MakeTypeError("observe_non_object", ["getNotifier"]); 556 throw MakeTypeError("observe_non_object", ["getNotifier"]);
562 557
563 if (ObjectIsFrozen(object)) return null; 558 if (ObjectIsFrozen(object)) return null;
564 559
560 if (!%ObjectWasCreatedInCurrentOrigin(object)) return null;
561
565 var objectInfo = ObjectInfoGetOrCreate(object); 562 var objectInfo = ObjectInfoGetOrCreate(object);
566 return ObjectInfoGetNotifier(objectInfo); 563 return ObjectInfoGetNotifier(objectInfo);
567 } 564 }
568 565
569 function CallbackDeliverPending(callback) { 566 function CallbackDeliverPending(callback) {
570 var callbackInfo = GetCallbackInfoMap().get(callback); 567 var callbackInfo = GetCallbackInfoMap().get(callback);
571 if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo)) 568 if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo))
572 return false; 569 return false;
573 570
574 // Clear the pending change records from callback and return it to its 571 // Clear the pending change records from callback and return it to its
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 InstallFunctions($Array, DONT_ENUM, $Array( 613 InstallFunctions($Array, DONT_ENUM, $Array(
617 "observe", ArrayObserve, 614 "observe", ArrayObserve,
618 "unobserve", ArrayUnobserve 615 "unobserve", ArrayUnobserve
619 )); 616 ));
620 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( 617 InstallFunctions(notifierPrototype, DONT_ENUM, $Array(
621 "notify", ObjectNotifierNotify, 618 "notify", ObjectNotifierNotify,
622 "performChange", ObjectNotifierPerformChange 619 "performChange", ObjectNotifierPerformChange
623 )); 620 ));
624 } 621 }
625 622
626 // Disable Object.observe API for M35. 623 SetupObjectObserve();
627 // SetupObjectObserve();
OLDNEW
« no previous file with comments | « src/api.cc ('k') | src/objects.h » ('j') | src/runtime.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698