-
Type:
Problem report
-
Resolution: Unresolved
-
Priority:
Trivial
-
None
-
Affects Version/s: 8.0.0beta2
-
Component/s: Frontend (F)
-
None
WHAT CHANGED
In 8.0, ui/js/common.js:114 defines the xor helper with Object.defineProperty:
Object.defineProperty(Array.prototype, 'xor',
{ value: function(arr) \{ ... },
enumerable: false
});
Attributes that are not named default to false, so the property is neither
writable nor configurable for the lifetime of the page. In 7.0 the same line is
a plain assignment (measured in the official image
zabbix/zabbix-web-nginx-pgsql:alpine-7.0), which leaves it writable and
configurable. 7.4 behaves like 7.0.
WHY IT BREAKS THIRD-PARTY FRONTEND MODULES
Assignment goes through [[Set]], and [[Set]] may not shadow a non-writable
inherited property in strict mode. Any library that builds a prototype from
Array.prototype and then uses Object.assign on it now throws.
Minimal reproduction, browser console on any 8.0 page - no module required:
const proto = Object.create(Array.prototype);
Object.assign(proto, { xor: function ()
});
// 7.0 / 7.4: ok
// 8.0: TypeError: Cannot assign to read only property 'xor' of object
CONCRETE IMPACT
Cytoscape.js does exactly this: it creates its collection prototype with
Object.create(Array.prototype) so collections behave array-like, then
Object.assigns its own xor (symmetric difference) onto it. On 8.0 the library
aborts while loading, window.cytoscape stays undefined, and the page that uses
it renders empty - with no error anywhere in the module's own code, because the
module code never runs. That makes it hard to trace: the failure surfaces in a
third-party bundle, not where the cause is.
Two independent installati