-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: avoid stack overflow with spread operator
A customer cannot scan their project with a supposedly very large dependency graph because as soon as it reaches our back-end, we get a stack overflow error. It was identified that the error is due to the combination of Array.push() and the spread operator. For reference: nodejs/node#16870 To reproduce, create an array of size 2^17 then do [].push(...myArray); This fix replaces all uses of push() and spread with a simple loop.
- Loading branch information
1 parent
fd8b897
commit 0bd6afb
Showing
2 changed files
with
43 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import * as depGraphLib from '../../src'; | ||
|
||
const dependencyName = 'needle'; | ||
|
||
async function generateLargeGraph(width: number) { | ||
const builder = new depGraphLib.DepGraphBuilder( | ||
{ name: 'npm' }, | ||
{ name: 'root', version: '1.2.3' }, | ||
); | ||
const rootNodeId = 'root-node'; | ||
|
||
const deepDependency = { name: dependencyName, version: '1.2.3' }; | ||
|
||
builder.addPkgNode(deepDependency, dependencyName); | ||
builder.connectDep(rootNodeId, dependencyName); | ||
|
||
for (let j = 0; j < width; j++) { | ||
const shallowName = `id-${j}`; | ||
const shallowDependency = { name: shallowName, version: '1.2.3' }; | ||
|
||
builder.addPkgNode(shallowDependency, shallowName); | ||
builder.connectDep(rootNodeId, shallowName); | ||
builder.connectDep(shallowName, dependencyName); | ||
} | ||
|
||
return builder.build(); | ||
} | ||
|
||
describe('stress tests', () => { | ||
test('pkgPathsToRoot() does not cause stack overflow for large dep-graphs', async () => { | ||
const graph = await generateLargeGraph(125000); | ||
|
||
const result = graph.pkgPathsToRoot({ name: dependencyName, version: '1.2.3' }); | ||
expect(result).toBeDefined(); | ||
}); | ||
}); |