Index: lib/content/snippets.js |
=================================================================== |
--- a/lib/content/snippets.js |
+++ b/lib/content/snippets.js |
@@ -693,24 +693,51 @@ |
// 2176782336 is 36^6 which mean 6 chars [a-z0-9] |
// 60466176 is 36^5 |
// 2176782336 - 60466176 = 2116316160. This ensure to always have 6 |
// chars even if Math.random() returns its minimum value 0.0 |
// |
return Math.floor(Math.random() * 2116316160 + 60466176).toString(36); |
} |
-function wrapPropertyAccess(object, property, descriptor) |
+function wrapPropertyAccess(object, property, descriptor, magic) |
{ |
- let currentDescriptor = Object.getOwnPropertyDescriptor(object, property); |
- if (currentDescriptor && !currentDescriptor.configurable) |
- return false; |
+ let dot = property.indexOf("."); |
+ if (dot == -1) |
+ { |
+ // simple property case. |
+ let currentDescriptor = Object.getOwnPropertyDescriptor(object, property); |
+ if (currentDescriptor && !currentDescriptor.configurable) |
+ return false; |
+ |
+ Object.defineProperty(object, property, descriptor); |
+ return true; |
+ } |
+ let prop = property.slice(0, dot); |
Manish Jethani
2019/02/03 14:30:38
We could just call this `name` instead of `prop`.
hub
2019/02/04 15:48:02
Done.
|
+ property = property.slice(dot + 1); |
+ let value = object[prop]; |
+ if (typeof value != "undefined") |
Manish Jethani
2019/02/03 14:30:38
What if `value` is `null`? I think we want to chec
hub
2019/02/04 15:48:02
Actually I think we want `value intanceof Object`
|
+ return wrapPropertyAccess(value, property, descriptor); |
- Object.defineProperty(object, property, descriptor); |
- return true; |
+ let currentDescriptor = Object.getOwnPropertyDescriptor(object, prop); |
+ if (currentDescriptor && currentDescriptor.set && |
+ magic && currentDescriptor.set.hasOwnProperty(magic)) |
+ { |
+ return true; |
+ } |
+ |
+ let v; |
+ let setter = a => |
+ { |
+ v = a; |
+ if (a instanceof Object) |
Manish Jethani
2019/02/03 14:30:38
This check is inconsistent with the one above. I t
hub
2019/02/04 15:48:02
`a instanceof Object` is false if a is null. Unlik
Manish Jethani
2019/02/04 17:56:33
We've been here before:
https://hg.adblockplus.or
hub
2019/02/04 19:54:36
So be it. And this actually make the test pass on
|
+ wrapPropertyAccess(a, property, descriptor, magic); |
+ }; |
+ setter[magic] = undefined; |
Manish Jethani
2019/02/03 14:30:38
If we just want to tag the setter, I think it's be
hub
2019/02/04 15:48:03
undefined is good. We check it with hasOwnProperty
|
+ Object.defineProperty(object, prop, {get: () => v, set: setter}); |
} |
/** |
* Overrides the <code>onerror</code> handler to discard tagged error messages |
* from our property wrapping. |
* |
* @param {string} magic The magic string that tags the error message. |
*/ |
@@ -744,17 +771,17 @@ |
let rid = randomId(); |
function abort() |
{ |
throw new ReferenceError(rid); |
} |
- if (wrapPropertyAccess(window, property, {get: abort, set() {}})) |
+ if (wrapPropertyAccess(window, property, {get: abort, set() {}}, rid)) |
overrideOnError(rid); |
} |
exports["abort-on-property-read"] = makeInjector(abortOnPropertyRead, |
wrapPropertyAccess, |
overrideOnError, |
randomId); |
@@ -776,17 +803,17 @@ |
let rid = randomId(); |
function abort() |
{ |
throw new ReferenceError(rid); |
} |
- if (wrapPropertyAccess(window, property, {set: abort})) |
+ if (wrapPropertyAccess(window, property, {set: abort}, rid)) |
overrideOnError(rid); |
} |
exports["abort-on-property-write"] = makeInjector(abortOnPropertyWrite, |
wrapPropertyAccess, |
overrideOnError, |
randomId); |
@@ -839,15 +866,15 @@ |
}, |
set(value) |
{ |
abort(); |
currentValue = value; |
} |
}; |
- if (wrapPropertyAccess(object, name, descriptor)) |
+ if (wrapPropertyAccess(object, name, descriptor, rid)) |
overrideOnError(rid); |
} |
exports["abort-current-inline-script"] = |
makeInjector(abortCurrentInlineScript, wrapPropertyAccess, toRegExp, |
overrideOnError, regexEscape, randomId); |