@contrast/route-coverage 1.53.2 → 1.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/install/express.js +35 -12
- package/lib/install/fastify/fastify.js +1 -1
- package/package.json +9 -9
package/lib/install/express.js
CHANGED
|
@@ -31,6 +31,7 @@ const {
|
|
|
31
31
|
} = require('@contrast/common');
|
|
32
32
|
const Core = require('@contrast/core/lib/ioc/core');
|
|
33
33
|
|
|
34
|
+
const MAX_REPEATED_TRAVERSALS = 10;
|
|
34
35
|
const METHODS = [
|
|
35
36
|
'all',
|
|
36
37
|
'get',
|
|
@@ -260,8 +261,25 @@ class ExpressInstrumentation {
|
|
|
260
261
|
post(data) {
|
|
261
262
|
const { result } = data;
|
|
262
263
|
if (!result || !data._store || !data[kMetaKey]?.template) return;
|
|
264
|
+
|
|
263
265
|
// if the layer matches, we know to push corresponding path to store's template segments.
|
|
264
266
|
// we pop this value from the array in hook to all `next` callbacks below.
|
|
267
|
+
|
|
268
|
+
// special case if the layer has a route instance (.use wasn't called to create layer)
|
|
269
|
+
if (data.obj.route) {
|
|
270
|
+
// the layer might match the path, but the route might not support the method.
|
|
271
|
+
// in this case don't capture the current template segment.
|
|
272
|
+
const store = core.scopes.sources.getStore();
|
|
273
|
+
if (
|
|
274
|
+
store.sourceInfo?.method &&
|
|
275
|
+
data.obj.route?.methods &&
|
|
276
|
+
!data.obj.route.methods[store.sourceInfo.method] &&
|
|
277
|
+
!data.obj.route.methods._all
|
|
278
|
+
) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
265
283
|
data._store.templateSegments.push(data[kMetaKey].template);
|
|
266
284
|
}
|
|
267
285
|
});
|
|
@@ -423,17 +441,24 @@ class ExpressInstrumentation {
|
|
|
423
441
|
|
|
424
442
|
// only visit Layer instances
|
|
425
443
|
const maybeLayer = target[key];
|
|
426
|
-
if (
|
|
427
|
-
maybeLayer?.constructor?.name == 'Layer' &&
|
|
428
|
-
!maybeLayer?.stack?.length
|
|
429
|
-
) {
|
|
430
|
-
let _data = data.get(maybeLayer);
|
|
431
|
-
|
|
432
|
-
if (!_data) {
|
|
433
|
-
_data = { paths: [] };
|
|
434
|
-
data.set(maybeLayer, _data);
|
|
435
|
-
}
|
|
436
444
|
|
|
445
|
+
const _data = data.get(maybeLayer) ?? { paths: [], visitCount: 0 };
|
|
446
|
+
data.set(maybeLayer, _data);
|
|
447
|
+
|
|
448
|
+
// track number of times we've visited a certain member across all paths.
|
|
449
|
+
_data.visitCount++;
|
|
450
|
+
_data.paths.push([...path]); // copy because path argument mutates
|
|
451
|
+
|
|
452
|
+
// if we've exceeded a "reasonable" number of visits to a certain member
|
|
453
|
+
// it's likely we've encountered circular references and should stop
|
|
454
|
+
// traversing that path to prevent a stack overflow.
|
|
455
|
+
if (_data.visitCount > MAX_REPEATED_TRAVERSALS) {
|
|
456
|
+
path.pop();
|
|
457
|
+
continue loopKeys;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Only execute the callback on valid Layer objects.
|
|
461
|
+
if (maybeLayer?.constructor?.name == 'Layer' && !maybeLayer?.stack?.length) {
|
|
437
462
|
// you can mount a router on itself
|
|
438
463
|
// prevent infinitely recursing into self-mounted routers
|
|
439
464
|
for (const visitedPath of _data.paths) {
|
|
@@ -447,8 +472,6 @@ class ExpressInstrumentation {
|
|
|
447
472
|
}
|
|
448
473
|
}
|
|
449
474
|
|
|
450
|
-
_data.paths.push([...path]); // copy because path argument mutates
|
|
451
|
-
|
|
452
475
|
const halt = cb(path, key, maybeLayer, target) === false;
|
|
453
476
|
if (halt) return;
|
|
454
477
|
}
|
|
@@ -123,7 +123,7 @@ module.exports = function init(core) {
|
|
|
123
123
|
* and prepareRoute({ options: { method, url, options, handler }})
|
|
124
124
|
*/
|
|
125
125
|
[
|
|
126
|
-
{ version: '>=
|
|
126
|
+
{ version: '>=4 <4.1.0', routeObj: false },
|
|
127
127
|
{ version: '>=4.1.0 <6', routeObj: true },
|
|
128
128
|
].forEach(({ version, routeObj }) => {
|
|
129
129
|
// See ../utils/methods
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/route-coverage",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.55.0",
|
|
4
4
|
"description": "Handles route discovery and observation",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
|
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
"test": "bash ../scripts/test.sh"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@contrast/common": "1.
|
|
24
|
-
"@contrast/config": "1.
|
|
25
|
-
"@contrast/core": "1.
|
|
26
|
-
"@contrast/dep-hooks": "1.
|
|
23
|
+
"@contrast/common": "1.41.0",
|
|
24
|
+
"@contrast/config": "1.57.0",
|
|
25
|
+
"@contrast/core": "1.62.0",
|
|
26
|
+
"@contrast/dep-hooks": "1.31.0",
|
|
27
27
|
"@contrast/fn-inspect": "^5.0.2",
|
|
28
|
-
"@contrast/logger": "1.
|
|
29
|
-
"@contrast/patcher": "1.
|
|
30
|
-
"@contrast/rewriter": "1.
|
|
31
|
-
"@contrast/scopes": "1.
|
|
28
|
+
"@contrast/logger": "1.35.0",
|
|
29
|
+
"@contrast/patcher": "1.34.0",
|
|
30
|
+
"@contrast/rewriter": "1.39.0",
|
|
31
|
+
"@contrast/scopes": "1.32.0",
|
|
32
32
|
"semver": "^7.6.0"
|
|
33
33
|
}
|
|
34
34
|
}
|