Skip to content

Avoid stack overflow in completions #28286

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

Closed
wants to merge 1 commit into from

Conversation

sandersn
Copy link
Member

@sandersn sandersn commented Nov 1, 2018

In symbolCanBeReferfencedAtTypeLocation, telemetry reports that 3.1.3 has a stack overflow in the recursive case that checks exportedSymbols. I believe that the cause is a commonjs module with both export assignment and export property assignments via an alias [1], but I haven't been able to repro the crash since telemetry only reports a stack. Nevertheless, I think the correct fix is just to not recur in the case that an exported symbol is identical to its containing module.

// @Filename: module.js
exports.version = 'hi'
function alias() { }
module.exports = alias

// @Filename: use.js
var m = require('./module')
m.al/**/

I expected the overflow to happen when requesting completions at /**/ but it didn't.

Fixes #27872

In symbolCanBeReferfencedAtTypeLocation, 3.1.3 has a stack overflow in
the recursive case that checks exportedSymbols. I believe that the cause
is a commonjs module with both export assignment and export property
assignments via an alias [1], but I haven't been able to repro the
crash. Nevertheless, I think the correct fix is just to not recur in the
case that an exported symbol is identical to its containing module.

```js
// @filename: module.js
exports.version = 'hi'
function alias() { }
module.exports = alias

// @filename: use.js
var m = require('./module')
m.al/**/
```

I expected the overflow to happen when requesting completions at `/**/`
but it didn't.
@sandersn sandersn requested review from sheetalkamat and a user November 1, 2018 16:14
@@ -1142,7 +1142,7 @@ namespace ts.Completions {
const exportedSymbols = typeChecker.getExportsOfModule(symbol);
// If the exported symbols contains type,
// symbol can be referenced at locations where type is allowed
return exportedSymbols.some(symbolCanBeReferencedAtTypeLocation);
return exportedSymbols.some(ex => ex !== symbol && symbolCanBeReferencedAtTypeLocation(ex));
Copy link
Member

Choose a reason for hiding this comment

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

Could the repro be exportedSymbol => some other symbol => exportedSymbol or some such recursion?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, although for the pattern I referenced above, from #28133, has the cycle directly between two symbols.

@ghost
Copy link

ghost commented Nov 1, 2018

The reason that doesn't reproduce the issue is it's not recursive, and isn't tested at a type location so symbolCanBeReferencedAtTypeLocation isn't called anyway. You can reproduce this with a recursive module or namespace like namespace N { export import M = N; }. See #28295

@sandersn sandersn closed this Nov 1, 2018
@sheetalkamat sheetalkamat deleted the avoid-stack-overflow-in-completion branch November 1, 2018 22:59
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 this pull request may close these issues.

Stack overflow symbolCanBeReferencedAtTypeLocation
2 participants