Skip to content

Commit 220060d

Browse files
committed
feat: config tree size limit for yarn and npm.
1 parent 4b84895 commit 220060d

7 files changed

+49
-3
lines changed

config.default.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"NPM_TREE_SIZE_LIMIT": 6.0e6,
3+
"YARN_TREE_SIZE_LIMIT": 6.0e6
4+
}

lib/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { loadConfig } from 'snyk-config';
2+
export const config: any = loadConfig(__dirname + '../..');

lib/parsers/package-lock-parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as _ from 'lodash';
22
import * as graphlib from 'graphlib';
33
import * as uuid from 'uuid/v4';
4+
import { config } from '../config';
45
import { setImmediatePromise } from '../set-immediate-promise';
56

67
import {
@@ -143,10 +144,9 @@ export class PackageLockParser implements LockfileParser {
143144

144145
// number of dependencies including root one
145146
let treeSize = 1;
146-
const treeSizeLimit = 6.0e6;
147147
for (const dep of topLevelDeps) {
148148
// tree size limit should be 6 millions.
149-
if (treeSize > treeSizeLimit) {
149+
if (treeSize > config.NPM_TREE_SIZE_LIMIT) {
150150
throw new TreeSizeLimitError();
151151
}
152152
// if any of top level dependencies is a part of cycle

lib/parsers/yarn-lock-parse.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import {
1818
InvalidUserInputError,
1919
UnsupportedRuntimeError,
2020
OutOfSyncError,
21+
TreeSizeLimitError,
2122
} from '../errors';
23+
import { config } from '../config';
2224

2325
const EVENT_PROCESSING_CONCURRENCY = 5;
2426

@@ -158,6 +160,10 @@ export class YarnLockParser implements LockfileParser {
158160
});
159161

160162
for (const [subName, subVersion] of subDependencies) {
163+
// tree size limit should be 6 millions.
164+
if (this.treeSize > config.YARN_TREE_SIZE_LIMIT) {
165+
throw new TreeSizeLimitError();
166+
}
161167
const subDependency: DepTreeDep = {
162168
labels: {
163169
scope: tree.labels!.scope, // propagate scope label only

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"graphlib": "^2.1.5",
3535
"lodash": "^4.17.14",
3636
"p-map": "2.1.0",
37+
"snyk-config": "^3.0.0",
3738
"source-map-support": "^0.5.7",
3839
"tslib": "^1.9.3",
3940
"uuid": "^3.3.2"

test/lib/package-lock-depTree.test.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22
// Shebang is required, and file *has* to be executable: chmod +x file.test.js
33
// See: https://github.com/tapjs/node-tap/issues/313#issuecomment-250067741
44
import { test } from 'tap';
5+
import { config } from '../../lib/config';
56
import { buildDepTreeFromFiles } from '../../lib';
67
import * as fs from 'fs';
78
import * as _ from 'lodash';
8-
import { InvalidUserInputError, OutOfSyncError } from '../../lib/errors';
9+
import {
10+
InvalidUserInputError,
11+
OutOfSyncError,
12+
TreeSizeLimitError,
13+
} from '../../lib/errors';
914

1015
const load = (filename) =>
1116
JSON.parse(fs.readFileSync(`${__dirname}/fixtures/${filename}`, 'utf8'));
@@ -250,3 +255,16 @@ test('`package.json` with file as version', async (t) => {
250255

251256
t.deepEqual(depTree, expectedDepTree, 'Tree generated as expected');
252257
});
258+
259+
test('Npm Tree size exceeds the allowed limit of 500 dependencies.', async (t) => {
260+
config.NPM_TREE_SIZE_LIMIT = 500;
261+
t.rejects(
262+
buildDepTreeFromFiles(
263+
`${__dirname}/fixtures/goof/`,
264+
'package.json',
265+
'package-lock.json',
266+
),
267+
new TreeSizeLimitError(),
268+
'Expected error is thrown',
269+
);
270+
});

test/lib/yarn.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Shebang is required, and file *has* to be executable: chmod +x file.test.js
33
// See: https://github.com/tapjs/node-tap/issues/313#issuecomment-250067741
44
import { test } from 'tap';
5+
import { config } from '../../lib/config';
56
import { buildDepTreeFromFiles, getYarnWorkspacesFromFiles } from '../../lib';
67
import getRuntimeVersion from '../../lib/get-node-runtime-version';
78
import * as fs from 'fs';
@@ -10,6 +11,7 @@ import {
1011
UnsupportedRuntimeError,
1112
InvalidUserInputError,
1213
OutOfSyncError,
14+
TreeSizeLimitError,
1315
} from '../../lib/errors';
1416

1517
if (getRuntimeVersion() < 6) {
@@ -250,3 +252,16 @@ test('identify package.json as Not a workspace project', async (t) => {
250252
);
251253
t.is(workspaces, false, 'Not a yarn workspace');
252254
});
255+
256+
test('Yarn Tree size exceeds the allowed limit of 500 dependencies.', async (t) => {
257+
config.YARN_TREE_SIZE_LIMIT = 500;
258+
t.rejects(
259+
buildDepTreeFromFiles(
260+
`${__dirname}/fixtures/goof/`,
261+
'package.json',
262+
'yarn.lock',
263+
),
264+
new TreeSizeLimitError(),
265+
'Expected error is thrown',
266+
);
267+
});

0 commit comments

Comments
 (0)