-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
document.all is not virtualizable #2
Comments
Spec in question: A lot more details about this issue here: |
Yes @Jack-Works we need to explicitly state the limits on the virtualizability we intend to support. We should explicitly state that we will not support emulating |
Instead I suggest to remove the magic behavior on document.all. Let it be truthy can solve this problem. |
You mean in the main spec? |
Yes, I'm mean by deleting it in the main spec. Falsy value of document.all is used to prevent feature detection on the document.all, but there are better ways to do it. Like the browser can only make it falsy when using the literal to infer to it like what we do on the eval. e.g.: if (document.all) { // this direct access evaluate to false
}
var x = document.all
if (x) { // this indirect access evaluate to true
} Make the indirect access to document.all evaluate to truthy, most of the security issues in sandboxes can be resolved (because they never direct access document.all). |
It would almost certainly break the web to change that behavior at this point; otherwise we wouldn’t have added the IsHTMLDDA slot to the spec. |
Maybe we should try to make it falsy meanwhile less harmful to code that doesn't using document.all |
I'm not sure what you mean; the weird part is that it's a falsy object. Making it truthy would break websites; making it not an object would break websites. What change are you suggesting? |
I'm suggesting that it still be a falsy object but only when the website is really using it. |
IMO, there are 3 things to look at:
For us, at salesforce, we are virtualizing this by setting |
Let the typeof check the isHTMLDDL slot recursively through the Proxy object that can resolve the visualizability. However, what I really mean is the falsy evaluation is harmful to web security. It's better to disable this behavior on newer websites. (for example in module context or use a "legacy site list") |
I @Jack-Works I do not want to add any complexity to the proxy mechanism to deal with this ugly special case.
I agree it is harmful, and I agree that we should find a way to disable it, or change it to some behavior that can be expressed in JS. I am not familiar with how it is currently used and what the compat issues are in trying to change its behavior. I do encourage you and all of us to continue searching for a way out of the current mess. |
if (document.all) {
// code that uses `document.all`, for ancient browsers
} else if (document.getElementById) {
// code that uses `document.getElementById`, for “modern” browsers
}
// Internet Explorer
if (document.all) {
useActiveX()
}
// Netscape Navigator
else {
useOldButStillWorkingCode()
} It's the common pattern that why we need If we can change the spec like:
// literal usages
if (document.all) // still falsy
Boolean(document.all) // still falsy
!!document.all // still falsy
typeof document.all // "undefined"
// non literal usages
function typeof_(x) { return typeof x }
typeof_(document.all) // "object" Then the old code will still be working, and newer code won't be hacked by the This way is somewhat like +function x() {
let y = 1
eval('y = 2')
console.log(y) // logs 2
}() +function x() {
let y = 1
let indirectEval = eval
indirectEval('y = 2')
console.log(y) // logs 1
}() |
@Jack-Works unfortunately that does not work in a membrane implementation because the target of the proxy is not the real object/function, but a shadow of it, what we call the shadow target, in order to preserve the language semantics. |
By claudepache tc39/ecma262#673 (comment)
By claudepache tc39/ecma262#673 (comment) I think it is a good thing to do. Change the meaning of (See the code example above) // literal usages
typeof document.all // "undefined"
// non literal usages
function typeof_(x) { return typeof x }
typeof_(document.all) // "object" |
I’d be very surprised if that would be web compatible - but itd be worth you making the case to web browsers to gather telemetry about it. |
I correct myself: Copying how direct eval is specified would not work (unless you’re very optimistic about what is needed for web compatibility), because Another interesting case: should we “support” (*) The technical reason is that |
curious about it. do browsers already do that? does the telemetry data for this public or visible in some way? |
FYI, 16 years ago, hacking |
function foo() {
this.ie = document.all;
}
var f = new foo();
if (f.ie) // ... Damn! It's impossible to do that in the end Hmm but, does the percent of usage changed now? Just like how we delete other web platform features. |
Just to notice, Symbol polyfills rewrite Before if (typeof document.all === 'undefined') {...} After function _typeof(val) { /* helper function body... */}
if (_typeof(document.all) === 'undefined') {...} |
The code that using a transpiler, won't use document.all IMO |
The npm dependencies that use document.all may still be transpiled in some condition. (e.g. some dependency used new syntax that old browser do not support, so they got transpiled all together) |
@Jack-Works now that people are sometimes unwisely transpiling node_modules - code they didn't write - that's not necessarily the case. |
No description provided.
The text was updated successfully, but these errors were encountered: