Skip to content
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

BUG: Module exporting undeclared name should be a syntax error #5778

Closed
rhuanjl opened this issue Oct 13, 2018 · 8 comments · Fixed by #5837
Closed

BUG: Module exporting undeclared name should be a syntax error #5778

rhuanjl opened this issue Oct 13, 2018 · 8 comments · Fixed by #5837
Assignees

Comments

@rhuanjl
Copy link
Collaborator

rhuanjl commented Oct 13, 2018

Another bug I found whilst working on #5759 though I do not currently have a fix planned for this.

Per
https://tc39.github.io/ecma262/#sec-module-semantics-static-semantics-early-errors
It is a Syntax Error if any element of the ExportedBindings of
ModuleItemList does not also occur in either the VarDeclaredNames of
ModuleItemList, or the LexicallyDeclaredNames of ModuleItemList.

POC:

//start.js
import {Fun} from "./other.js";
print(Fun);
//other.js
export {anything as Fun};

Note the same repros if instead of "anything" you use any other undeclared name OR use a global like Number or Array or if you don't alias "anything".

Output with ch: undefined, jsc and v8 throw Syntax Errors
(Can't do an eshost repro at the moment as eshost doesn't yet interact with ch's module flag)

This causes numerous test262 failures.

@rhuanjl rhuanjl changed the title BUG: exporting undeclared name should be a syntax error BUG: Module exporting undeclared name should be a syntax error Oct 13, 2018
chakrabot pushed a commit that referenced this issue Oct 31, 2018
Merge pull request #5779 from rhuanjl:exportNamespace

This PR does the following:
1. implements support for `export * as ns from "module"` syntax a normative change PR to ecma262 which has tc39 consensus
See spec diff: https://spectranaut.github.io/proposal-export-ns-from/
See normative PR here: tc39/ecma262#1174 (comment)
This is placed behind a flag but set to default enabled
2. Adds some relevant tests
3. Fixes a bug where duplicate exports weren't always a syntax error (implementing this feature correctly without fixing this bug would have been awkward)
4. Some drive by syntax error message improvement for duplicate exports and alias'd exports
    - "Syntax error: Syntax error" -> "Syntax error: Duplicate export of name '%s'"
    - "Syntax error: Syntax error" -> "Syntax error: 'as' is only valid if followed by an identifier."

There are unfortunately some remaining related test262 failures due to #5778 and #5501

closes #5759
fixes #5777
@rhuanjl
Copy link
Collaborator Author

rhuanjl commented Nov 3, 2018

I've been thinking about how to fix this - it seems it needs to involve adding a step at the end of parsing a module that re-checks any names exported via export {namesHere} without a from clause to confirm if they were locally defined and if not seek back to the relevant line and raise a syntax error.

@boingoing
Copy link
Contributor

Seems like something we should be able to do at name binding. We do push a pidref to 'anything' when we export it, right? When we bind names, we could throw a SyntaxError if we find a referenced name with no declaration.

@rhuanjl
Copy link
Collaborator Author

rhuanjl commented Nov 6, 2018

Would that permit a valid case like this:

export {foo};
var foo = 5;

Whilst catching the invalid cases I put in the first post?

@pleath
Copy link
Contributor

pleath commented Nov 6, 2018

Yes, it would. @boingoing is referring to the way the parser binds names to declarations. The "push" records the fact that there was a reference to the given name in the current scope. Binding takes place when parsing of the current scope is completed. So the reference can lexically precede or follow the declaration.

@rhuanjl
Copy link
Collaborator Author

rhuanjl commented Nov 6, 2018

Thanks @pleath that makes sense.

I was going to make a PR to fix this but see it's now assigned to you @boingoing want me to give it a go still or have you got it?

@boingoing
Copy link
Contributor

@rhuanjl, feel free to take a stab at it if you're motivated. I haven't looked-into the fix yet. We can help if you need some in that area of the code. If you're not feeling it I can take this one on, as well. 👍

@rhuanjl
Copy link
Collaborator Author

rhuanjl commented Nov 13, 2018

I had a go at trying to do this but didn't get far, unless I'm missing something currently no pid ref is pushed for an exported name unless the export is also variable declaration (in which case it can't possibly hit this error).

And I couldn't quite work out how to push a pid ref for the name and have it be accessible in the right place without making it into a variable declaration which would obviously be wrong.

@pleath
Copy link
Contributor

pleath commented Nov 18, 2018

You're right, no pid ref is pushed in this case. It looks like we implemented it without attempting to bind the exported name to a declaration. Either we missed this requirement in the spec or implemented an earlier spec that didn't contain the requirement.

What you'll want to do is call PushPidRef from Parser::AddModuleImportOrExportEntry, passing in the IdentPtr of the local name, and store the resulting PidRefStack* on the export record. Binding will fill in the Symbol* on the PidRefStack. When we later resolve the export entries, a null Symbol* will indicate an undeclared name. Note that this has to be done whether buildAST is false or true, so the caller of AddModuleImportOrExportEntry will have to make the call in both cases.

Does all that make sense?

chakrabot pushed a commit that referenced this issue Nov 22, 2018
Merge pull request #5837 from rhuanjl:undefinedNames

This PR causes CC to throw a syntax error when a module is parsed that exports a name with no local definition, this is per point 4 of https://tc39.github.io/ecma262/#sec-module-semantics-static-semantics-early-errors

@boingoing @pleath Thanks for the help with how to do this, please could one of you review?

fix: #5778
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants