We are wrapping primitives in objects when tainted. While this is the required way to implement this, it has strange side effects. Generally, number objects (e.g., new Number(42)) behave differently in JavaScript compared to numeric literals (i.e., 42 in this example).
This has quite a few downstream effects and might lead to (potential) changes in program semantics.
For example:
// case 0
if (!(Number.tainted(0))) console.log("no") // prints nothing
// case 1
if (!(0)) console.log("no") // prints no
// case 2
if (!(new Number(0))) console.log("no") // prints nothing
One idea, similar to how the fix with maps (af544cf) is implemented, is to unbox tainted numbers upon usage. I believe @0drai has a fix for this prepared.
This seems like a generally valid approach, but might change programs semantics if people have code that effectively works like this: Number.tainted(new Number(42)). By unboxing it, we would lose the information that it originally was an object, and change case 2 above into case 1.
I think this should not be overly problematic, but it might be something to keep in mind.
We are wrapping primitives in objects when tainted. While this is the required way to implement this, it has strange side effects. Generally, number objects (e.g.,
new Number(42)) behave differently in JavaScript compared to numeric literals (i.e.,42in this example).This has quite a few downstream effects and might lead to (potential) changes in program semantics.
For example:
One idea, similar to how the fix with maps (af544cf) is implemented, is to unbox tainted numbers upon usage. I believe @0drai has a fix for this prepared.
This seems like a generally valid approach, but might change programs semantics if people have code that effectively works like this:
Number.tainted(new Number(42)). By unboxing it, we would lose the information that it originally was an object, and change case 2 above into case 1.I think this should not be overly problematic, but it might be something to keep in mind.