Commit 0438433a authored by jsbell's avatar jsbell Committed by Commit bot

IndexedDB: Avoid side effects for array key conversion w/ HasOwnProperty

When converting arrays to keys, only own properties should be
considered, much like clones. Otherwise, this opens up the behavior to
side effects via getters on the Object/Array prototype even if the
value being converted to a key is a clone.

BUG=641101
R=haraken@chromium.org

Review-Url: https://codereview.chromium.org/2279343002
Cr-Commit-Position: refs/heads/master@{#415172}
parent 7917e6ae
...@@ -14,6 +14,7 @@ indexeddb_test( ...@@ -14,6 +14,7 @@ indexeddb_test(
var setter_called = false; var setter_called = false;
Object.defineProperty(Object.prototype, '10', { Object.defineProperty(Object.prototype, '10', {
configurable: true,
set: t.step_func(function(value) { setter_called = true; }) set: t.step_func(function(value) { setter_called = true; })
}); });
request.onerror = t.unreached_func('request should not fail'); request.onerror = t.unreached_func('request should not fail');
...@@ -25,6 +26,8 @@ indexeddb_test( ...@@ -25,6 +26,8 @@ indexeddb_test(
'Result should have own-property overriding prototype setter.'); 'Result should have own-property overriding prototype setter.');
assert_equals(result[10], 'key', assert_equals(result[10], 'key',
'Result should have expected property.'); 'Result should have expected property.');
delete Object.prototype['10'];
t.done(); t.done();
}); });
}, },
...@@ -42,6 +45,7 @@ indexeddb_test( ...@@ -42,6 +45,7 @@ indexeddb_test(
var setter_called = false; var setter_called = false;
Object.defineProperty(Object.prototype, 'id', { Object.defineProperty(Object.prototype, 'id', {
configurable: true,
set: t.step_func(function(value) { setter_called = true; }) set: t.step_func(function(value) { setter_called = true; })
}); });
request.onerror = t.unreached_func('request should not fail'); request.onerror = t.unreached_func('request should not fail');
...@@ -53,6 +57,8 @@ indexeddb_test( ...@@ -53,6 +57,8 @@ indexeddb_test(
'Result should have own-property overriding prototype setter.'); 'Result should have own-property overriding prototype setter.');
assert_equals(result.id, 1, assert_equals(result.id, 1,
'Own property should match primary key generator value'); 'Own property should match primary key generator value');
delete Object.prototype['id'];
t.done(); t.done();
}); });
}, },
...@@ -384,4 +390,38 @@ indexeddb_test( ...@@ -384,4 +390,38 @@ indexeddb_test(
}, },
'Key path evaluation: Exceptions from enumerable getters on prototype' 'Key path evaluation: Exceptions from enumerable getters on prototype'
); );
indexeddb_test(
function(t, db) {
var store = db.createObjectStore('store');
store.createIndex('index', 'index0');
},
function(t, db) {
var tx = db.transaction('store', 'readwrite');
var array = [];
array[99] = 1;
var getter_called = 0;
var prop = '50';
Object.defineProperty(Object.prototype, prop, {
enumerable: true, configurable: true,
get: function() {
++getter_called;
return 'foo';
}
});
var request = tx.objectStore('store').put({index0: array}, 'key');
request.onerror = t.unreached_func('put should not fail');
request.onsuccess = t.step_func(function() {
assert_equals(getter_called, 0,
'Prototype getter should not be called');
delete Object.prototype[prop];
t.done();
});
},
'Array key conversion should not invoke prototype getters'
);
</script> </script>
...@@ -213,9 +213,12 @@ static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Local<v8::Value> ...@@ -213,9 +213,12 @@ static IDBKey* createIDBKeyFromValue(v8::Isolate* isolate, v8::Local<v8::Value>
IDBKey::KeyArray subkeys; IDBKey::KeyArray subkeys;
uint32_t length = array->Length(); uint32_t length = array->Length();
v8::TryCatch block(isolate); v8::TryCatch block(isolate);
v8::Local<v8::Context> context = isolate->GetCurrentContext();
for (uint32_t i = 0; i < length; ++i) { for (uint32_t i = 0; i < length; ++i) {
if (!v8CallBoolean(array->HasOwnProperty(context, i)))
return nullptr;
v8::Local<v8::Value> item; v8::Local<v8::Value> item;
if (!v8Call(array->Get(isolate->GetCurrentContext(), i), item, block)) { if (!v8Call(array->Get(context, i), item, block)) {
exceptionState.rethrowV8Exception(block.Exception()); exceptionState.rethrowV8Exception(block.Exception());
return nullptr; return nullptr;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment