-
Notifications
You must be signed in to change notification settings - Fork 19
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
fix this
binding in Function constructor
#17
Conversation
Hi @Jack-Works , reviewing this PR, I see that we did not have enough test cases to cover my concerns. See #18 where I propose to add these. Aside from that concern, the other concern I have with this PR is it attempts to emulate one aspect of sloppy (non-strict) behavior when the Function text does not begin with Given these reactions, I must apologize for having left in the |
Looking over your PR again, I realize that #18 still doesn't have the needed extra test. Hold on. |
Added t.equal(F.call(undefined), undefined); which would fool return Reflect.apply(f, this || globalThis, arguments); into returning |
I'm loading my whole application into the Realm and I found it is broken. Debugging it, I found it is breaking in the lodash library. Lodash detects global variables in a wrong way (they write them before we have globalThis in Javascript) and "return this" is just a quite common technique in the classic JavaScript world. At least 2 dependencies in my project use this pattern. If new Function cannot simulate a sloppy mode, or let just say, getting "this", I think it's not a correct way of emulating a sandbox. |
To be more concise. I'm working on a project that provides a "polyfill" to WebExtension API. In browser extensions, content scripts run in an isolated world and I'm implementing it by Realm shim. Then I put my extension code into this emulated web extension environment, its breaking due to "this" in Function is undefined. If I let other extensions run in my environment, they may crash due to cannot get the global object. Giving them the global object is not harmful and improve the compatibility with the standard "new Function" behavior. |
I'm curious about the default strict behavior, is that a by-design in the spec, or due to technical restrictions code in sloppy mode may leak out of the sandbox? |
Hi @Jack-Works , thanks. This helps a lot. If we provided a Could you point me at the relevant places in lodash or other libraries that probe for the global? Are they using the Emulating the WebExtension API is cool! Eager to hear more about this project. Is there anything publicly visible to look at? |
The strict-only behavior is required by the technique we use to emulate the proposal, the so-called 8 magic lines of code https://www.youtube.com/watch?v=mSNxsn0pK74&list=PLKr-mvz8uvUg70w0yKGfytaDqxiIBNo_L&t=799 . If we allowed the user to write a sloppy function, they could use it to obtain the genuine global object which would totally break the illusion the shim is trying to create. As for the proposal, it is likely to support both modes, with sloppy likely the default and strict-only being an option. Anticipating that, the shim should probably insist that the strict-only option be passed in, throwing otherwise. Thus, code that works with the shim would continue to work with the full proposal even if strict-only is not the default. |
Reopening until we understand the issue better, and hopefully succeed somehow at not breaking your use case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We must find a different technique to address this use case. See #17 (comment)
I have fixed lodash by detecting Facebook's regenerator-runtime library is commonly used in transpile async function into ES5/ES6.
In https://github.com/facebook/regenerator/blob/master/packages/regenerator-runtime/runtime.js#L725 With my forked version of Realms, all of the code works properly now. |
Content script is running in a context that shares DOMs but isolates JS environment. (https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Xray_vision) Now realms assuming outside of the sandbox is safe, and inside of the sandbox is dangerous. In my case, both outside AND inside of the sandbox are dangerous. I need to prevent attacks to the content in the sandbox(in browser extension environment we have a high permission |
Excepts commits in this pr, I forked to another repo to make some changes that I think may not be accepted by this project but I need them to let realms works for my project.
|
On https://github.com/DimensionDev/realms-shim/commit/be2c2728d266035bbff7786f5d25f274b90c30fe Where did you run into html-like comments? This one really surprises me. Thanks. |
On https://github.com/DimensionDev/realms-shim/commit/44ab25eca8d928a070f813fd9dcd1216f31c00db |
On https://github.com/DimensionDev/realms-shim/commit/55963b0b26c92235123afb0a95c251e0f48fd59d I have filed a bug against WebKit/Safari/JSC on this. Will try to find. I think we will accept your fix here. |
I found that the string "-->" occurred in Agoric/ERTP, where it appeared as somebody writing an ASCII-art arrow as part of the documentation in a Javascript comment. It was caught by the realms-shim HTML-comment rejector. Perhaps we should only be concerned with "<!--" and not "-->". |
No, we need to be equally concerned with both. The Javascript parsing rule for these is that each is treated separately as a line comment. They are not bracketed. Because this hazard itself makes ambiguous whether we are even in a comment or literal string or whatever, it would be quite hazardous to do a parser-based-only rejection of these. We could, but we would need to very carefully review it. On that one, we should also ask @waldemarhorwat to double check our work. We should still reject these by default. The non-default options setting should have a clear name discouraging its use. |
@Jack-Works why is |
@Jack-Works what is your current status/understanding of your need for access to global this? |
Try to evaluate React and ReactDOM the unminified version, both import-like and html-like comments appear. The import-like comment is teaching you how to async import a React Component and load it. The html-like comment is inside of a picture (or table?) in comments |
Yeah I said it's a hack way to resolve this problem. If relams want to support non-strict assignment, there must be a better implementation than mine. |
I'm not writing code for relamed environment, I'm creating a realm that can run the existing code. So my usage is the community's usage, they will write all bad design like (and they are not using |
@Jack-Works, thanks for fixing this issue in lodash! @jdalton, thanks for merging this in so quickly!
In any JavaScript in which any of this is relevant, the platform will already support both generators and async function. So why shim them? I ask because the comment you link to has the generous invitation:
Even though this doesn't quite fit our constraints, I'd be happy to post an issue explaining our constraints if relevant. But given the purpose of regenerator, I'm unclear on how I'd claim that our constraints are relevant. |
I'm not transpile my code to ES5, but the libraries I'm using, its dependencies, its dependencies' dependencies, ... etc may transpile their code into ES5 and use regenerator-runtime. I can't control that.. |
With 969f1fe I fixed that Realms shim will pollute outside world Function.prototype.constructor which cause a failure in my production env |
this
binding in Functionthis
binding in Function
@erights I have fixed the tests. |
this
binding in Functionthis
binding in Function constructor
From #17 (comment)
We plan to make these syntactic rejections switchable. As always, the default will be the safe setting --- reject --- but you'll be able to turn these off by an option setting.
The "sloppyGlobalsMode" option does this.
We merged your separate PR on this issue. Thanks! |
Regarding the remaining const InnerFunction = Function; // the post initialization safe one
function OuterFunction(...args) {
const inner = new InnerFunction(...args);
return Reflect.apply(inner, this || globalThis, args);
} As this would be a one-off that doesn't really shim any behavior we would propose, I suggest that it should remain as post-initialization user code, rather than incorporating it as an option in the realms-shim. If so, can we close this? |
Seems good to me, I'll try it if it's working in our production |
@Jack-Works Is there anything I can help you with in this pull request? Let me know! |
Ah I didn't touch the web extension polyfill these days. |
That works well in our project I guess |
Hi @Jack-Works , does #17 (comment) work for you? Can we close this? |
It may works for us 🧐🧐 I tried it in our project and it seems no error has thrown. I don't know if it is fixed |
Ok, @Jack-Works , I'll close this. But if you run into a problem, please reopen. Thanks. |
Other unrelated fixes are move to other prs
fix: pollution to outside world Function.prototype.constructor(see fix global function get polluted close #52 #63 )disabled rejectHtmlComments and rejectImportExpressions(see allow configurable Realm transforms #42 )non-strict assignment(see Eval sloppy globals #33 )disabled alwaysThrowHandler on WKWebKit(see fix: getPrototypeOf trap get called in safari #62 )