Skip to content

Commit

Permalink
Merge pull request #2323 from svaarala/fix-putvar-ptrstab
Browse files Browse the repository at this point in the history
Fix unstable valstack pointer in putprop
  • Loading branch information
svaarala authored Jun 14, 2020
2 parents 798d3a2 + 4ba871a commit d500048
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
1 change: 1 addition & 0 deletions releases/releases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1366,3 +1366,4 @@ duktape_releases:
- "Fix failing assert for CBOR.encode() when argument is a zero-size dynamic plain array (GH-2316, GH-2318)"
- "Fix pointer overflow in String.prototype.startsWith/endsWith() with certain arguments (GH-2320)"
- "Fix assertion failure and incorrect behavior in some enumeration cases involving inherited duplicate keys (GH-2322)"
- "Fix unstable pointer in 'putvar' which could trigger e.g. in a with(proxy) statement (GH-2323)"
14 changes: 9 additions & 5 deletions src-input/duk_js_var.c
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,7 @@ void duk__putvar_helper(duk_hthread *thr,
duk_tval *val,
duk_bool_t strict) {
duk__id_lookup_result ref;
duk_tval tv_tmp_val;
duk_tval tv_tmp_obj;
duk_tval tv_tmp_key;
duk_bool_t parents;
Expand All @@ -1298,10 +1299,13 @@ void duk__putvar_helper(duk_hthread *thr,
DUK_ASSERT(val != NULL);
/* env and act may be NULL */

DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);
DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);
DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);
DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);
DUK_ASSERT_REFCOUNT_NONZERO_TVAL(val);

DUK_TVAL_SET_TVAL(&tv_tmp_val, val); /* Stabilize. */
val = NULL;

/*
* In strict mode E5 protects 'eval' and 'arguments' from being
* assigned to (or even declared anywhere). Attempt to do so
Expand Down Expand Up @@ -1333,15 +1337,15 @@ void duk__putvar_helper(duk_hthread *thr,

tv_val = ref.value;
DUK_ASSERT(tv_val != NULL);
DUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, val); /* side effects */
DUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, &tv_tmp_val); /* side effects */

/* ref.value invalidated here */
} else {
DUK_ASSERT(ref.holder != NULL);

DUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);
DUK_TVAL_SET_STRING(&tv_tmp_key, name);
(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, strict);
(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, &tv_tmp_val, strict);

/* ref.value invalidated here */
}
Expand All @@ -1366,7 +1370,7 @@ void duk__putvar_helper(duk_hthread *thr,

DUK_TVAL_SET_OBJECT(&tv_tmp_obj, thr->builtins[DUK_BIDX_GLOBAL]);
DUK_TVAL_SET_STRING(&tv_tmp_key, name);
(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, 0); /* 0 = no throw */
(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, &tv_tmp_val, 0); /* 0 = no throw */

/* NB: 'val' may be invalidated here because put_value may realloc valstack,
* caller beware.
Expand Down
20 changes: 20 additions & 0 deletions tests/ecmascript/test-bug-putvar-ptrstab-proxywith-gh2323.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*===
done
===*/

function main() {
var v3 = [2,2,2,2,2,2,2,2,2];
var v4 = v3;
var v5 = {constructor:String,call:String,apply:String,get:String,construct:String,defineProperty:String,has:String,preventExtensions:String};
v3.length = 1343;
var v7 = new Proxy(v4,v5);
with (v7) {
var v9 = 0;
}
}
try {
main();
} catch (e) {
print(e.stack || e);
}
print('done');

0 comments on commit d500048

Please sign in to comment.