summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2019-11-26 11:35:23 +0100
committerJo-Philipp Wich <jo@mein.io>2019-11-26 11:39:14 +0100
commit4a08fdd2d374083366787c4124e6b4de48bf7b77 (patch)
treeca30681b8ce6c3c6193c9d4ee573b8f8110b0e96
parent374c23cdab53c5681acafb561977d927c361408a (diff)
luci-base: luci.js: further nested Class.super() call fixes
Use stacks keyed by class id + symbol internally to not clobber the prototype scope pointer when repeatedly calling super() in invoked methods. Ref: https://github.com/openwrt/luci/issues/3316#issuecomment-558531111 Fixes: 374c23cda ("luci-base: luci.js: properly handle nested Class.super() calls") Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--modules/luci-base/htdocs/luci-static/resources/luci.js32
1 files changed, 19 insertions, 13 deletions
diff --git a/modules/luci-base/htdocs/luci-static/resources/luci.js b/modules/luci-base/htdocs/luci-static/resources/luci.js
index 738a5b4cb..808ab0c5c 100644
--- a/modules/luci-base/htdocs/luci-static/resources/luci.js
+++ b/modules/luci-base/htdocs/luci-static/resources/luci.js
@@ -269,33 +269,39 @@
if (key == null)
return null;
- var slotIdx = this.__id__ + '.' + key;
+ var slotIdx = this.__id__ + '.' + key,
+ symStack = superContext[slotIdx],
+ protoCtx = null;
- for (superContext[slotIdx] = Object.getPrototypeOf(superContext[slotIdx] ||
- Object.getPrototypeOf(this));
- superContext[slotIdx] && !superContext[slotIdx].hasOwnProperty(key);
- superContext[slotIdx] = Object.getPrototypeOf(superContext[slotIdx])) {}
+ for (protoCtx = Object.getPrototypeOf(symStack ? symStack[0] : Object.getPrototypeOf(this));
+ protoCtx != null && !protoCtx.hasOwnProperty(key);
+ protoCtx = Object.getPrototypeOf(protoCtx)) {}
- if (!superContext[slotIdx]) {
- delete superContext[slotIdx];
+ if (protoCtx == null)
return null;
- }
- var res = superContext[slotIdx][key];
+ var res = protoCtx[key];
if (arguments.length > 1) {
- if (typeof(res) != 'function') {
- delete superContext[slotIdx];
+ if (typeof(res) != 'function')
throw new ReferenceError(key + ' is not a function in base class');
- }
if (typeof(callArgs) != 'object')
callArgs = this.varargs(arguments, 1);
+ if (symStack)
+ symStack.unshift(protoCtx);
+ else
+ superContext[slotIdx] = [ protoCtx ];
+
res = res.apply(this, callArgs);
+
+ if (symStack && symStack.length > 1)
+ symStack.shift(protoCtx);
+ else
+ delete superContext[slotIdx];
}
- delete superContext[slotIdx];
return res;
},