Skip to content

Conversation

weswigham
Copy link
Member

@weswigham weswigham commented Jul 22, 2017

@sandersn @DanielRosenwasser
We just started parsing jsdoc types in a lot of places in order to better provide errors when they are used outside of jsdoc positions. This caused us to think they we may still be parsing a parameter list when we think we're parsing an arrow function head, when it's really just a parenthesized expression split across two lines. This isn't in and of itself bad, as this will error when we realize its not an arrow function, BUT what was wrong was that nothing was consuming the token used to make the jsdoc-ish type members in these cases, causing us to repeatedly parse (and issue errors for, thereby running out of memory) the same expression, over and over.

With this small change, we simply consume the token appropriately when parsing parameters and have something jsdocish as the token, allowing us to leave the loop and realize our guess at an arrow function is completely wrong.

This fixes the errors caught by these tests (try them in your local checkout of master and be amazed! 7 characters to crash!) and fixes our internal RWC suite OOM failure. 🌞

@weswigham weswigham requested review from sandersn and a user July 22, 2017 00:38
@@ -1881,6 +1881,11 @@ namespace ts {
if (considerSemicolonAsDelimiter && token() === SyntaxKind.SemicolonToken && !scanner.hasPrecedingLineBreak()) {
nextToken();
}
else if (isJSDocParameterStart() && parsingContext & (1 << ParsingContext.Parameters)) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseDelimitedList is called in a lot of different places, so it seems wrong to put something in here that would only be used in one particular situation. It also looks like this would be the only place in the parser that we compare parsingContext to a particular value. Could this be moved into the parseElement handler?

token() === SyntaxKind.AtToken || token() === SyntaxKind.ThisKeyword || isJSDocParameterStart();
}

function isJSDocParameterStart(): boolean {
Copy link
Member

@DanielRosenwasser DanielRosenwasser Jul 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems weird that isStartOfParameter calls isJSDocParameterStart and not the other way around. One is kind of a superset of the other.

@weswigham
Copy link
Member Author

@DanielRosenwasser @Andy-MS I think I have a much, much nicer fix now. I realized that a special case from three years ago was, on inspection, avoiding the same bug (but a different specialization of it) - I've made the check very broad now. If we consume no tokens when attempting to parse a parameter (for any reason), then we will consume a token to avoid an infinite loop (and thereby actually yield our parse errors).

Additionally, while I was inside parseParameter, I also saw that there was a comment which was 1. outdated and 2. not attached to anything, so I removed it.

// contexts. In addition, parameter initializers are semantically disallowed in
// overload signatures. So parameter initializers are transitively disallowed in
// ambient contexts.
const zeroLengthName = getFullWidth(node.name) === 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider leaving the previous check so that we advance to ? in foo(static?). We can then have a secondary check that advances the token if we haven't consumed anything by capturing scanner.getStartPos() at the top of the function (before line 2217) and comparing it at the bottom of the function to ensure we advance.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's done.

@weswigham weswigham force-pushed the fix-parameter-parsing-infinite-loop branch from 9312ad3 to 98d5830 Compare July 25, 2017 00:51
@rbuckton rbuckton merged commit d74cb24 into microsoft:master Jul 25, 2017
@weswigham weswigham deleted the fix-parameter-parsing-infinite-loop branch July 25, 2017 07:41
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants