Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fix potential corruption issue caused by delete [].__proto__ (fix #…
  • Loading branch information
gfwilliams committed Feb 8, 2022
1 parent e00585c commit e069be2
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 4 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Expand Up @@ -9,6 +9,7 @@
Much-improved whitespace lexing code using single jumptable - 3% speed increase
Allow `process.memory(false)` to get memory info but skip GC
Graphics: fix height calculation bug in fillRect/clearRect when given an object with w/h as an argument
Fix potential corruption issue caused by `delete [].__proto__` (fix #2142)

2v12 : nRF52840: Flow control XOFF is now sent at only 3/8th full - delays in BLE mean we can sometimes fill our 1k input buffer otherwise
__FILE__ is now set correctly for apps (fixes 2v11 regression)
Expand Down
16 changes: 13 additions & 3 deletions src/jsparse.c
Expand Up @@ -952,7 +952,12 @@ static NO_INLINE JsVar *jspGetNamedFieldInParents(JsVar *object, const char* nam
} else if (strcmp(name, JSPARSE_INHERITS_VAR)==0) {
const char *objName = jswGetBasicObjectName(object);
if (objName) {
child = jspNewPrototype(objName);
JsVar *p = jsvSkipNameAndUnLock(jspNewPrototype(objName));
// jspNewPrototype returns a 'prototype' name that's already a child of eg. an array
// Create a new 'name' called __proto__ that links to it
JsVar *i = jsvNewFromString(JSPARSE_INHERITS_VAR);
if (p) child = jsvCreateNewChild(object, i, p);
jsvUnLock(i);
}
}
}
Expand Down Expand Up @@ -1372,8 +1377,13 @@ NO_INLINE JsVar *jspeFactorDelete() {
if (!parent && jsvIsChild(execInfo.root, a))
parent = jsvLockAgain(execInfo.root);

if (jsvHasChildren(parent)) {
#ifdef DEBUG
if (jsvHasChildren(parent)) assert(jsvIsChild(parent, a));
#endif
if (jsvHasChildren(parent) && jsvIsChild(parent, a)) {
// else remove properly.
/* we use jsvIsChild here just in case. delete probably isn't called
that often so it pays to be safe */
if (jsvIsArray(parent)) {
// For arrays, we must make sure we don't change the length
JsVarInt l = jsvGetArrayLength(parent);
Expand Down Expand Up @@ -2848,7 +2858,7 @@ JsVar *jspNewBuiltin(const char *instanceOf) {
return objFunc;
}

/// Create a new Class of the given instance and return its prototype
/// Create a new Class of the given instance and return its prototype (as a name 'prototype')
NO_INLINE JsVar *jspNewPrototype(const char *instanceOf) {
JsVar *objFuncName = jsvFindChildFromString(execInfo.root, instanceOf, true);
if (!objFuncName) // out of memory
Expand Down
2 changes: 1 addition & 1 deletion src/jsparse.h
Expand Up @@ -37,7 +37,7 @@ bool jspCheckStackPosition();
/// Create a new built-in object that jswrapper can use to check for built-in functions
JsVar *jspNewBuiltin(const char *name);

/// Create a new Class of the given instance and return its prototype
/// Create a new Class of the given instance and return its prototype (as a name 'prototype')
NO_INLINE JsVar *jspNewPrototype(const char *instanceOf);

/** Create a new object of the given instance and add it to root with name 'name'.
Expand Down
4 changes: 4 additions & 0 deletions src/jsvar.c
Expand Up @@ -2555,6 +2555,7 @@ void jsvAddName(JsVar *parent, JsVar *namedChild) {
}

if (insertAfter) {
assert(jsvIsName(insertAfter));
if (jsvGetNextSibling(insertAfter)) {
// great, we're in the middle...
JsVar *insertBefore = jsvLock(jsvGetNextSibling(insertAfter));
Expand Down Expand Up @@ -2761,6 +2762,9 @@ JsVar *jsvFindChildFromVar(JsVar *parent, JsVar *childName, bool addIfNotFound)
void jsvRemoveChild(JsVar *parent, JsVar *child) {
assert(jsvHasChildren(parent));
assert(jsvIsName(child));
#ifdef DEBUG
assert(jsvIsChild(parent, child));
#endif
JsVarRef childref = jsvGetRef(child);
bool wasChild = false;
// unlink from parent
Expand Down

0 comments on commit e069be2

Please sign in to comment.