Browse Source

Bug testcase for a few e_idx stability bugs

pull/1096/head
Sami Vaarala 8 years ago
parent
commit
da57edd4ce
  1. 55
      tests/ecmascript/test-bug-object-defprop-eidx-1.js
  2. 56
      tests/ecmascript/test-bug-object-defprop-eidx-2.js
  3. 57
      tests/ecmascript/test-bug-object-delprop-eidx-1.js

55
tests/ecmascript/test-bug-object-defprop-eidx-1.js

@ -0,0 +1,55 @@
/*
* Demonstrate a bug in Object.defineProperty() accessor-to-data-property
* convertion when a previous value has a finalizer which modifies the object
* which is going through Object.defineProperty().
*
* See comments in test-bug-object-delprop-eidx-1.js.
*
* https://github.com/svaarala/duktape/pull/1096
*/
/*===
Object.defineProperty() to convert .prop to a data property
finalizer, modify object
finalizer done
Object.defineProperty() done
{prop:"replaced",oops:345,"dummy-0":"foo","dummy-1":"foo","dummy-2":"foo","dummy-3":"foo","dummy-4":"foo","dummy-5":"foo","dummy-6":"foo","dummy-7":"foo","dummy-8":"foo","dummy-9":"foo"}
===*/
var obj = {};
function myFinalizer() {
var i;
print('finalizer, modify object');
delete obj.first;
for (i = 0; i < 10; i++) {
// i limit 2 is enough to trigger the bug now, overshoot a bit.
obj['dummy-' + i] = 'foo';
}
print('finalizer done');
}
function accessorToDataTest() {
obj.first = 123;
Object.defineProperty(obj, 'prop', { get: new Function(''), configurable: true, enumerable: true });
Object.getOwnPropertyDescriptor(obj, 'prop').get.prototype = null; // break circular ref
Duktape.fin(Object.getOwnPropertyDescriptor(obj, 'prop').get, myFinalizer);
obj.oops = 345;
print('Object.defineProperty() to convert .prop to a data property');
Object.defineProperty(obj, 'prop', { value: 'replaced' });
print('Object.defineProperty() done');
print(Duktape.enc('jx', obj));
}
try {
accessorToDataTest();
} catch (e) {
print(e.stack || e);
}

56
tests/ecmascript/test-bug-object-defprop-eidx-2.js

@ -0,0 +1,56 @@
/*
* Demonstrate a bug in Object.defineProperty() data-to-accessor-property
* convertion when a previous value has a finalizer which modifies the object
* which is going through Object.defineProperty().
*
* For some reason this test doesn't trigger the bug in practice.
*
* See comments in test-bug-object-delprop-eidx-1.js.
*
* https://github.com/svaarala/duktape/pull/1096
*/
/*===
Object.defineProperty() to convert .prop to an accessor property
finalizer, modify object
finalizer done
Object.defineProperty() done
{prop:"getter",oops:"keep","dummy-0":"foo","dummy-1":"foo","dummy-2":"foo","dummy-3":"foo","dummy-4":"foo","dummy-5":"foo","dummy-6":"foo","dummy-7":"foo","dummy-8":"foo","dummy-9":"foo"}
===*/
var obj = {};
function myFinalizer() {
var i;
print('finalizer, modify object');
delete obj.first;
for (i = 0; i < 10; i++) {
// i limit 2 is enough to trigger the bug now, overshoot a bit.
obj['dummy-' + i] = 'foo';
}
print('finalizer done');
}
function accessorToDataTest() {
obj.first = 123;
Object.defineProperty(obj, 'prop', { value: {}, configurable: true, enumerable: true });
Duktape.fin(Object.getOwnPropertyDescriptor(obj, 'prop').value, myFinalizer);
obj.oops = 'keep';
print('Object.defineProperty() to convert .prop to an accessor property');
Object.defineProperty(obj, 'prop', { get: new Function('return "getter";'), set: new Function() });
print('Object.defineProperty() done');
print(Duktape.enc('jx', obj));
}
try {
accessorToDataTest();
} catch (e) {
print(e.stack || e);
}

57
tests/ecmascript/test-bug-object-delprop-eidx-1.js

@ -0,0 +1,57 @@
/*
* Demonstrate bug in internal delprop helper when previous value has a
* finalizer which modifies the same object which is going through a delprop.
* https://github.com/svaarala/duktape/pull/1096
*/
/*===
deleting obj.prop
finalizer, modify object
finalizer done
deleted obj.prop
{oops:345,"dummy-0":"foo","dummy-1":"foo","dummy-2":"foo","dummy-3":"foo","dummy-4":"foo","dummy-5":"foo","dummy-6":"foo","dummy-7":"foo","dummy-8":"foo","dummy-9":"foo"}
===*/
var obj = {};
function myFinalizer() {
var i;
print('finalizer, modify object');
// To cause the runtime e_idx to change, delete the 'first' property which
// leaves an entry part gap. Then insert enough properties to cause a
// property table resize, so that 'prop' moves into the gap. Delprop
// continues updating the slot before this move, i.e. the property
// which follows 'prop'.
delete obj.first;
for (i = 0; i < 10; i++) {
// i limit 2 is enough to trigger the bug now, overshoot a bit.
obj['dummy-' + i] = 'foo';
}
print('finalizer done');
}
function test() {
obj.first = 123; // gets deleted
obj.prop = {}; // gets deleted
obj.oops = 345;
Duktape.fin(obj.prop, myFinalizer);
print('deleting obj.prop');
delete obj.prop;
print('deleted obj.prop');
// When the bug triggers, 'oops' get deleted while 'prop' remains,
// but 'prop' value is undefined. The delprop update has updated
// two unrelated slots due to the finalizer activity.
print(Duktape.enc('jx', obj));
}
try {
test();
} catch (e) {
print(e.stack || e);
}
Loading…
Cancel
Save