mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-22 15:16:33 -08:00
feat(nodejs): parse package.json files alongside package-lock.json (#2916)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
This commit is contained in:
@@ -65,13 +65,13 @@ func TestFilesystem(t *testing.T) {
|
||||
golden: "testdata/gomod-skip.json.golden",
|
||||
},
|
||||
{
|
||||
name: "nodejs",
|
||||
name: "npm",
|
||||
args: args{
|
||||
scanner: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/fs/nodejs",
|
||||
input: "testdata/fixtures/fs/npm",
|
||||
listAllPkgs: true,
|
||||
},
|
||||
golden: "testdata/nodejs.json.golden",
|
||||
golden: "testdata/npm.json.golden",
|
||||
},
|
||||
{
|
||||
name: "yarn",
|
||||
|
||||
113
integration/testdata/fixtures/fs/npm/node_modules/jquery/package.json
generated
vendored
Normal file
113
integration/testdata/fixtures/fs/npm/node_modules/jquery/package.json
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"name": "jquery",
|
||||
"title": "jQuery",
|
||||
"description": "JavaScript library for DOM operations",
|
||||
"version": "3.3.9",
|
||||
"main": "dist/jquery.js",
|
||||
"homepage": "https://jquery.com",
|
||||
"author": {
|
||||
"name": "JS Foundation and other contributors",
|
||||
"url": "https://github.com/jquery/jquery/blob/3.4.0/AUTHORS.txt"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jquery/jquery.git"
|
||||
},
|
||||
"keywords": [
|
||||
"jquery",
|
||||
"javascript",
|
||||
"browser",
|
||||
"library"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/jquery/jquery/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.3.3",
|
||||
"@babel/plugin-transform-for-of": "7.2.0",
|
||||
"commitplease": "3.2.0",
|
||||
"core-js": "2.6.5",
|
||||
"eslint-config-jquery": "1.0.1",
|
||||
"grunt": "1.0.3",
|
||||
"grunt-babel": "8.0.0",
|
||||
"grunt-cli": "1.3.2",
|
||||
"grunt-compare-size": "0.4.2",
|
||||
"grunt-contrib-uglify": "3.4.0",
|
||||
"grunt-contrib-watch": "1.1.0",
|
||||
"grunt-eslint": "21.0.0",
|
||||
"grunt-git-authors": "3.2.0",
|
||||
"grunt-jsonlint": "1.1.0",
|
||||
"grunt-karma": "3.0.1",
|
||||
"grunt-newer": "1.3.0",
|
||||
"grunt-npmcopy": "0.1.0",
|
||||
"gzip-js": "0.3.2",
|
||||
"husky": "1.3.1",
|
||||
"insight": "0.10.1",
|
||||
"jsdom": "13.2.0",
|
||||
"karma": "4.0.1",
|
||||
"karma-browserstack-launcher": "1.4.0",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-firefox-launcher": "1.1.0",
|
||||
"karma-ie-launcher": "1.0.0",
|
||||
"karma-jsdom-launcher": "7.1.0",
|
||||
"karma-qunit": "3.0.0",
|
||||
"load-grunt-tasks": "4.0.0",
|
||||
"native-promise-only": "0.8.1",
|
||||
"promises-aplus-tests": "2.1.2",
|
||||
"q": "1.5.1",
|
||||
"qunit": "2.9.2",
|
||||
"raw-body": "2.3.3",
|
||||
"requirejs": "2.3.6",
|
||||
"sinon": "2.3.7",
|
||||
"sizzle": "2.3.4",
|
||||
"strip-json-comments": "2.0.1",
|
||||
"testswarm": "1.1.0",
|
||||
"uglify-js": "3.4.7"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm install && grunt",
|
||||
"start": "grunt watch",
|
||||
"test:browserless": "grunt && grunt test:slow",
|
||||
"test:browser": "grunt && grunt karma:main",
|
||||
"test": "grunt && grunt test:slow && grunt karma:main",
|
||||
"jenkins": "npm run test:browserless"
|
||||
},
|
||||
"commitplease": {
|
||||
"nohook": true,
|
||||
"components": [
|
||||
"Docs",
|
||||
"Tests",
|
||||
"Build",
|
||||
"Support",
|
||||
"Release",
|
||||
"Core",
|
||||
"Ajax",
|
||||
"Attributes",
|
||||
"Callbacks",
|
||||
"CSS",
|
||||
"Data",
|
||||
"Deferred",
|
||||
"Deprecated",
|
||||
"Dimensions",
|
||||
"Effects",
|
||||
"Event",
|
||||
"Manipulation",
|
||||
"Offset",
|
||||
"Queue",
|
||||
"Selector",
|
||||
"Serialize",
|
||||
"Traversing",
|
||||
"Wrap"
|
||||
],
|
||||
"markerPattern": "^((clos|fix|resolv)(e[sd]|ing))|^(refs?)",
|
||||
"ticketPattern": "^((Closes|Fixes) ([a-zA-Z]{2,}-)[0-9]+)|^(Refs? [^#])"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"commit-msg": "node node_modules/commitplease",
|
||||
"pre-commit": "grunt lint:newer qunit_fixture"
|
||||
}
|
||||
}
|
||||
}
|
||||
35
integration/testdata/fixtures/fs/npm/node_modules/promise/package.json
generated
vendored
Normal file
35
integration/testdata/fixtures/fs/npm/node_modules/promise/package.json
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "promise",
|
||||
"version": "8.0.3",
|
||||
"description": "Bare bones Promises/A+ implementation",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"prepublish": "node build",
|
||||
"pretest": "node build",
|
||||
"pretest-resolve": "node build",
|
||||
"pretest-extensions": "node build",
|
||||
"pretest-memory-leak": "node build",
|
||||
"test": "mocha --bail --timeout 200 --slow 99999 -R dot && npm run test-memory-leak",
|
||||
"test-resolve": "mocha test/resolver-tests.js --timeout 200 --slow 999999",
|
||||
"test-extensions": "mocha test/extensions-tests.js --timeout 200 --slow 999999",
|
||||
"test-memory-leak": "node --expose-gc test/memory-leak.js",
|
||||
"coverage": "istanbul cover node_modules/mocha/bin/_mocha -- --bail --timeout 200 --slow 99999 -R dot"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/then/promise.git"
|
||||
},
|
||||
"author": "ForbesLindesay",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"acorn": "^1.0.1",
|
||||
"better-assert": "*",
|
||||
"istanbul": "^0.3.13",
|
||||
"mocha": "*",
|
||||
"promises-aplus-tests": "*",
|
||||
"rimraf": "^2.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"asap": "~2.0.6"
|
||||
}
|
||||
}
|
||||
27
integration/testdata/fixtures/fs/npm/node_modules/react-is/package.json
generated
vendored
Normal file
27
integration/testdata/fixtures/fs/npm/node_modules/react-is/package.json
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "react-is",
|
||||
"version": "16.8.6",
|
||||
"description": "Brand checking of React Elements.",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/react.git",
|
||||
"directory": "packages/react-is"
|
||||
},
|
||||
"keywords": [
|
||||
"react"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/facebook/react/issues"
|
||||
},
|
||||
"homepage": "https://reactjs.org/",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"build-info.json",
|
||||
"index.js",
|
||||
"cjs/",
|
||||
"umd/"
|
||||
]
|
||||
}
|
||||
39
integration/testdata/fixtures/fs/npm/node_modules/react/package.json
generated
vendored
Normal file
39
integration/testdata/fixtures/fs/npm/node_modules/react/package.json
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "react",
|
||||
"description": "React is a JavaScript library for building user interfaces.",
|
||||
"keywords": [
|
||||
"react"
|
||||
],
|
||||
"version": "16.8.6",
|
||||
"homepage": "https://reactjs.org/",
|
||||
"bugs": "https://github.com/facebook/react/issues",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"build-info.json",
|
||||
"index.js",
|
||||
"cjs/",
|
||||
"umd/"
|
||||
],
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/react.git",
|
||||
"directory": "packages/react"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"scheduler": "^0.13.6"
|
||||
},
|
||||
"browserify": {
|
||||
"transform": [
|
||||
"loose-envify"
|
||||
]
|
||||
}
|
||||
}
|
||||
105
integration/testdata/fixtures/fs/npm/node_modules/redux/package.json
generated
vendored
Normal file
105
integration/testdata/fixtures/fs/npm/node_modules/redux/package.json
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"name": "redux",
|
||||
"version": "4.0.1",
|
||||
"description": "Predictable state container for JavaScript apps",
|
||||
"license": "MIT",
|
||||
"homepage": "http://redux.js.org",
|
||||
"repository": "github:reduxjs/redux",
|
||||
"bugs": "https://github.com/reduxjs/redux/issues",
|
||||
"keywords": [
|
||||
"redux",
|
||||
"reducer",
|
||||
"state",
|
||||
"predictable",
|
||||
"functional",
|
||||
"immutable",
|
||||
"hot",
|
||||
"live",
|
||||
"replay",
|
||||
"flux",
|
||||
"elm"
|
||||
],
|
||||
"authors": [
|
||||
"Dan Abramov <dan.abramov@me.com> (https://github.com/gaearon)",
|
||||
"Andrew Clark <acdlite@me.com> (https://github.com/acdlite)"
|
||||
],
|
||||
"main": "lib/redux.js",
|
||||
"unpkg": "dist/redux.js",
|
||||
"module": "es/redux.js",
|
||||
"typings": "./index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"lib",
|
||||
"es",
|
||||
"src",
|
||||
"index.d.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf lib dist es coverage",
|
||||
"format": "prettier --write \"{src,test}/**/*.{js,ts}\" index.d.ts",
|
||||
"format:check": "prettier --list-different \"{src,test}/**/*.{js,ts}\" index.d.ts",
|
||||
"lint": "eslint src test",
|
||||
"pretest": "npm run build",
|
||||
"test": "jest",
|
||||
"test:watch": "npm test -- --watch",
|
||||
"test:cov": "npm test -- --coverage",
|
||||
"build": "rollup -c",
|
||||
"prepare": "npm run clean && npm run format:check && npm run lint && npm test",
|
||||
"examples:lint": "eslint examples",
|
||||
"examples:test": "cross-env CI=true babel-node examples/testAll.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"symbol-observable": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.0.0",
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/node": "^7.0.0",
|
||||
"@babel/plugin-external-helpers": "^7.0.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"@babel/register": "^7.0.0",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
"babel-eslint": "^9.0.0",
|
||||
"babel-jest": "^23.6.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"eslint": "^5.6.0",
|
||||
"eslint-config-react-app": "^2.1.0",
|
||||
"eslint-plugin-flowtype": "^2.50.1",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.1.1",
|
||||
"eslint-plugin-react": "^7.11.1",
|
||||
"glob": "^7.1.3",
|
||||
"jest": "^23.6.0",
|
||||
"prettier": "^1.14.3",
|
||||
"rimraf": "^2.6.2",
|
||||
"rollup": "^0.66.2",
|
||||
"rollup-plugin-babel": "^4.0.1",
|
||||
"rollup-plugin-node-resolve": "^3.4.0",
|
||||
"rollup-plugin-replace": "^2.0.0",
|
||||
"rollup-plugin-terser": "^3.0.0",
|
||||
"rxjs": "^6.3.2",
|
||||
"typescript": "^3.0.3",
|
||||
"typings-tester": "^0.3.2"
|
||||
},
|
||||
"npmName": "redux",
|
||||
"npmFileMap": [
|
||||
{
|
||||
"basePath": "/dist/",
|
||||
"files": [
|
||||
"*.js"
|
||||
]
|
||||
}
|
||||
],
|
||||
"browserify": {
|
||||
"transform": [
|
||||
"loose-envify"
|
||||
]
|
||||
},
|
||||
"jest": {
|
||||
"testRegex": "(/test/.*\\.spec.js)$"
|
||||
},
|
||||
"sideEffects": false
|
||||
}
|
||||
@@ -8,11 +8,6 @@
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||
},
|
||||
"jquery": {
|
||||
"version": "3.3.9",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.0.tgz",
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"SchemaVersion": 2,
|
||||
"ArtifactName": "testdata/fixtures/fs/nodejs",
|
||||
"ArtifactName": "testdata/fixtures/fs/npm",
|
||||
"ArtifactType": "filesystem",
|
||||
"Metadata": {
|
||||
"ImageConfig": {
|
||||
@@ -39,10 +39,13 @@
|
||||
"Version": "3.3.9",
|
||||
"Indirect": true,
|
||||
"Layer": {},
|
||||
"Licenses": [
|
||||
"MIT"
|
||||
],
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 16,
|
||||
"EndLine": 20
|
||||
"StartLine": 11,
|
||||
"EndLine": 15
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -54,21 +57,8 @@
|
||||
"Layer": {},
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 21,
|
||||
"EndLine": 25
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "lodash@4.17.4",
|
||||
"Name": "lodash",
|
||||
"Version": "4.17.4",
|
||||
"Indirect": true,
|
||||
"Layer": {},
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 11,
|
||||
"EndLine": 15
|
||||
"StartLine": 16,
|
||||
"EndLine": 20
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -83,8 +73,8 @@
|
||||
"Layer": {},
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 26,
|
||||
"EndLine": 33
|
||||
"StartLine": 21,
|
||||
"EndLine": 28
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -96,8 +86,8 @@
|
||||
"Layer": {},
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 34,
|
||||
"EndLine": 38
|
||||
"StartLine": 29,
|
||||
"EndLine": 33
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -110,10 +100,13 @@
|
||||
"asap@2.0.6"
|
||||
],
|
||||
"Layer": {},
|
||||
"Licenses": [
|
||||
"MIT"
|
||||
],
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 39,
|
||||
"EndLine": 46
|
||||
"StartLine": 34,
|
||||
"EndLine": 41
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -130,8 +123,8 @@
|
||||
"Layer": {},
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 47,
|
||||
"EndLine": 56
|
||||
"StartLine": 42,
|
||||
"EndLine": 51
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -147,10 +140,13 @@
|
||||
"scheduler@0.13.6"
|
||||
],
|
||||
"Layer": {},
|
||||
"Licenses": [
|
||||
"MIT"
|
||||
],
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 57,
|
||||
"EndLine": 67
|
||||
"StartLine": 52,
|
||||
"EndLine": 62
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -160,10 +156,13 @@
|
||||
"Version": "16.8.6",
|
||||
"Indirect": true,
|
||||
"Layer": {},
|
||||
"Licenses": [
|
||||
"MIT"
|
||||
],
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 68,
|
||||
"EndLine": 72
|
||||
"StartLine": 63,
|
||||
"EndLine": 67
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -177,10 +176,13 @@
|
||||
"symbol-observable@1.2.0"
|
||||
],
|
||||
"Layer": {},
|
||||
"Licenses": [
|
||||
"MIT"
|
||||
],
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 73,
|
||||
"EndLine": 81
|
||||
"StartLine": 68,
|
||||
"EndLine": 76
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -196,8 +198,8 @@
|
||||
"Layer": {},
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 82,
|
||||
"EndLine": 90
|
||||
"StartLine": 77,
|
||||
"EndLine": 85
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -209,8 +211,8 @@
|
||||
"Layer": {},
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 91,
|
||||
"EndLine": 95
|
||||
"StartLine": 86,
|
||||
"EndLine": 90
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -331,51 +333,6 @@
|
||||
],
|
||||
"PublishedDate": "2019-04-20T00:29:00Z",
|
||||
"LastModifiedDate": "2021-10-20T11:15:00Z"
|
||||
},
|
||||
{
|
||||
"VulnerabilityID": "CVE-2019-10744",
|
||||
"PkgID": "lodash@4.17.4",
|
||||
"PkgName": "lodash",
|
||||
"InstalledVersion": "4.17.4",
|
||||
"FixedVersion": "4.17.12",
|
||||
"Layer": {},
|
||||
"SeveritySource": "ghsa",
|
||||
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-10744",
|
||||
"DataSource": {
|
||||
"ID": "ghsa",
|
||||
"Name": "GitHub Security Advisory Npm",
|
||||
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm"
|
||||
},
|
||||
"Title": "nodejs-lodash: prototype pollution in defaultsDeep function leading to modifying properties",
|
||||
"Description": "Versions of lodash lower than 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.",
|
||||
"Severity": "CRITICAL",
|
||||
"CVSS": {
|
||||
"nvd": {
|
||||
"V2Vector": "AV:N/AC:L/Au:N/C:N/I:P/A:P",
|
||||
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H",
|
||||
"V2Score": 6.4,
|
||||
"V3Score": 9.1
|
||||
},
|
||||
"redhat": {
|
||||
"V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H",
|
||||
"V3Score": 9.1
|
||||
}
|
||||
},
|
||||
"References": [
|
||||
"https://access.redhat.com/errata/RHSA-2019:3024",
|
||||
"https://access.redhat.com/security/cve/CVE-2019-10744",
|
||||
"https://github.com/advisories/GHSA-jf85-cpcp-j695",
|
||||
"https://github.com/lodash/lodash/pull/4336",
|
||||
"https://nvd.nist.gov/vuln/detail/CVE-2019-10744",
|
||||
"https://security.netapp.com/advisory/ntap-20191004-0005/",
|
||||
"https://snyk.io/vuln/SNYK-JS-LODASH-450202",
|
||||
"https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp;utm_medium=RSS",
|
||||
"https://www.npmjs.com/advisories/1065",
|
||||
"https://www.oracle.com/security-alerts/cpujan2021.html",
|
||||
"https://www.oracle.com/security-alerts/cpuoct2020.html"
|
||||
],
|
||||
"PublishedDate": "2019-07-26T00:15:00Z",
|
||||
"LastModifiedDate": "2021-03-16T13:57:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,40 +2,99 @@ package npm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
dio "github.com/aquasecurity/go-dep-parser/pkg/io"
|
||||
"github.com/aquasecurity/go-dep-parser/pkg/nodejs/npm"
|
||||
"github.com/aquasecurity/go-dep-parser/pkg/nodejs/packagejson"
|
||||
godeptypes "github.com/aquasecurity/go-dep-parser/pkg/types"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/language"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/utils"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/utils/fsutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
analyzer.RegisterAnalyzer(&npmLibraryAnalyzer{})
|
||||
analyzer.RegisterPostAnalyzer(analyzer.TypeNpmPkgLock, newNpmLibraryAnalyzer)
|
||||
}
|
||||
|
||||
const version = 1
|
||||
const (
|
||||
version = 1
|
||||
)
|
||||
|
||||
var requiredFiles = []string{types.NpmPkgLock}
|
||||
type npmLibraryAnalyzer struct {
|
||||
lockParser godeptypes.Parser
|
||||
packageParser godeptypes.Parser
|
||||
}
|
||||
|
||||
type npmLibraryAnalyzer struct{}
|
||||
func newNpmLibraryAnalyzer(_ analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
|
||||
return &npmLibraryAnalyzer{
|
||||
lockParser: npm.NewParser(),
|
||||
packageParser: packagejson.NewParser(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a npmLibraryAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
|
||||
p := npm.NewParser()
|
||||
res, err := language.Analyze(types.Npm, input.FilePath, input.Content, p)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("unable to parse %s: %w", input.FilePath, err)
|
||||
func (a npmLibraryAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysisInput) (*analyzer.AnalysisResult, error) {
|
||||
// Parse package-lock.json
|
||||
required := func(path string, _ fs.DirEntry) bool {
|
||||
return filepath.Base(path) == types.NpmPkgLock
|
||||
}
|
||||
return res, nil
|
||||
|
||||
var apps []types.Application
|
||||
err := fsutils.WalkDir(input.FS, ".", required, func(filePath string, d fs.DirEntry, r dio.ReadSeekerAt) error {
|
||||
// Find all licenses from package.json files under node_modules dirs
|
||||
licenses, err := a.findLicenses(input.FS, filePath)
|
||||
if err != nil {
|
||||
log.Logger.Errorf("Unable to collect licenses: %s", err)
|
||||
licenses = map[string]string{}
|
||||
}
|
||||
|
||||
app, err := a.parseNpmPkgLock(input.FS, filePath)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parse error: %w", err)
|
||||
} else if app == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fill licenses
|
||||
for i, lib := range app.Libraries {
|
||||
if license, ok := licenses[lib.ID]; ok {
|
||||
app.Libraries[i].Licenses = []string{license}
|
||||
}
|
||||
}
|
||||
|
||||
apps = append(apps, *app)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("package-lock.json/package.json walk error: %w", err)
|
||||
}
|
||||
|
||||
return &analyzer.AnalysisResult{
|
||||
Applications: apps,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a npmLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool {
|
||||
fileName := filepath.Base(filePath)
|
||||
return utils.StringInSlice(fileName, requiredFiles)
|
||||
if fileName == types.NpmPkgLock {
|
||||
return true
|
||||
}
|
||||
// The file path to package.json - */node_modules/<package_name>/package.json
|
||||
// The path is slashed in analyzers.
|
||||
dirs := strings.Split(path.Dir(filePath), "/")
|
||||
if len(dirs) > 1 && dirs[len(dirs)-2] == "node_modules" && fileName == types.NpmPkg {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a npmLibraryAnalyzer) Type() analyzer.Type {
|
||||
@@ -45,3 +104,59 @@ func (a npmLibraryAnalyzer) Type() analyzer.Type {
|
||||
func (a npmLibraryAnalyzer) Version() int {
|
||||
return version
|
||||
}
|
||||
|
||||
func (a npmLibraryAnalyzer) parseNpmPkgLock(fsys fs.FS, path string) (*types.Application, error) {
|
||||
f, err := fsys.Open(path)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("file open error: %w", err)
|
||||
}
|
||||
defer func() { _ = f.Close() }()
|
||||
|
||||
file, ok := f.(dio.ReadSeekCloserAt)
|
||||
if !ok {
|
||||
return nil, xerrors.Errorf("type assertion error: %w", err)
|
||||
}
|
||||
|
||||
// parse package-lock.json file
|
||||
libs, deps, err := a.lockParser.Parse(file)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("unable to parse package-lock.json: %w", err)
|
||||
}
|
||||
return language.ToApplication(types.Npm, path, "", libs, deps), nil
|
||||
}
|
||||
|
||||
func (a npmLibraryAnalyzer) findLicenses(fsys fs.FS, lockPath string) (map[string]string, error) {
|
||||
dir := filepath.Dir(lockPath)
|
||||
root := path.Join(dir, "node_modules")
|
||||
if _, err := fs.Stat(fsys, root); errors.Is(err, fs.ErrNotExist) {
|
||||
log.Logger.Infof(`To collect the license information of packages in %q, "npm install" needs to be performed beforehand`, lockPath)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Parse package.json
|
||||
required := func(path string, _ fs.DirEntry) bool {
|
||||
return filepath.Base(path) == types.NpmPkg
|
||||
}
|
||||
|
||||
// Traverse node_modules dir and find licenses
|
||||
// Note that fs.FS is always slashed regardless of the platform,
|
||||
// and path.Join should be used rather than filepath.Join.
|
||||
licenses := map[string]string{}
|
||||
err := fsutils.WalkDir(fsys, root, required, func(filePath string, d fs.DirEntry, r dio.ReadSeekerAt) error {
|
||||
lib, _, err := a.packageParser.Parse(r)
|
||||
// package.json always contains only 1 library.
|
||||
// https://github.com/aquasecurity/go-dep-parser/blob/63a15cdc6bc3aaeb58c4172b275deadde4d55928/pkg/nodejs/packagejson/parse.go#L33-L37
|
||||
if err != nil {
|
||||
return xerrors.Errorf("unable to parse %q: %w", filePath, err)
|
||||
} else if len(lib) != 1 {
|
||||
return xerrors.Errorf("unable to parse %q", filePath)
|
||||
}
|
||||
|
||||
licenses[lib[0].ID] = lib[0].License
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("walk error: %w", err)
|
||||
}
|
||||
return licenses, nil
|
||||
}
|
||||
|
||||
@@ -12,23 +12,29 @@ import (
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
_ = log.InitLogger(false, true)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func Test_npmLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
inputFile string
|
||||
dir string
|
||||
want *analyzer.AnalysisResult
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "happy path",
|
||||
inputFile: "testdata/package-lock.json",
|
||||
name: "with node_modules",
|
||||
dir: "testdata/happy",
|
||||
want: &analyzer.AnalysisResult{
|
||||
Applications: []types.Application{
|
||||
{
|
||||
Type: types.Npm,
|
||||
FilePath: "testdata/package-lock.json",
|
||||
FilePath: "package-lock.json",
|
||||
Libraries: []types.Package{
|
||||
{
|
||||
ID: "array-flatten@1.1.1",
|
||||
@@ -48,6 +54,7 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
Version: "1.18.3",
|
||||
Indirect: true,
|
||||
DependsOn: []string{"debug@2.6.9"},
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: []types.Location{
|
||||
{
|
||||
StartLine: 17,
|
||||
@@ -61,6 +68,7 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
Version: "2.6.9",
|
||||
Indirect: true,
|
||||
DependsOn: []string{"ms@2.0.0"},
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: []types.Location{
|
||||
{
|
||||
StartLine: 25,
|
||||
@@ -78,6 +86,7 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
Version: "4.16.4",
|
||||
Indirect: true,
|
||||
DependsOn: []string{"debug@2.6.9"},
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: []types.Location{
|
||||
{
|
||||
StartLine: 40,
|
||||
@@ -90,6 +99,7 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
Name: "ms",
|
||||
Version: "2.0.0",
|
||||
Indirect: true,
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: []types.Location{
|
||||
{
|
||||
StartLine: 33,
|
||||
@@ -106,6 +116,7 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
Name: "ms",
|
||||
Version: "2.1.1",
|
||||
Indirect: true,
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: []types.Location{
|
||||
{
|
||||
StartLine: 63,
|
||||
@@ -118,27 +129,49 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "without node_modules",
|
||||
dir: "testdata/no-node_modules",
|
||||
want: &analyzer.AnalysisResult{
|
||||
Applications: []types.Application{
|
||||
{
|
||||
Type: types.Npm,
|
||||
FilePath: "package-lock.json",
|
||||
Libraries: []types.Package{
|
||||
{
|
||||
ID: "ms@2.1.1",
|
||||
Name: "ms",
|
||||
Version: "2.1.1",
|
||||
Indirect: true,
|
||||
Locations: []types.Location{
|
||||
{
|
||||
StartLine: 6,
|
||||
EndLine: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sad path",
|
||||
inputFile: "testdata/wrong.json",
|
||||
dir: "testdata/sad",
|
||||
wantErr: "unable to parse",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
f, err := os.Open(tt.inputFile)
|
||||
a, err := newNpmLibraryAnalyzer(analyzer.AnalyzerOptions{})
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = f.Close() }()
|
||||
|
||||
a := npmLibraryAnalyzer{}
|
||||
got, err := a.Analyze(context.Background(), analyzer.AnalysisInput{
|
||||
FilePath: tt.inputFile,
|
||||
Content: f,
|
||||
got, err := a.PostAnalyze(context.Background(), analyzer.PostAnalysisInput{
|
||||
FS: os.DirFS(tt.dir),
|
||||
})
|
||||
|
||||
if tt.wantErr != "" {
|
||||
require.NotNil(t, err)
|
||||
assert.Contains(t, err.Error(), tt.wantErr)
|
||||
assert.ErrorContains(t, err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -175,13 +208,18 @@ func Test_nodePkgLibraryAnalyzer_Required(t *testing.T) {
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "happy path",
|
||||
name: "lock file",
|
||||
filePath: "npm/package-lock.json",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "package.json",
|
||||
filePath: "npm/node_modules/ms/package.json",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "sad path",
|
||||
filePath: "npm/package.json",
|
||||
filePath: "npm/node_modules/package.json",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
49
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/body-parser/node_modules/debug/package.json
generated
vendored
Normal file
49
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/body-parser/node_modules/debug/package.json
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "debug",
|
||||
"version": "2.6.9",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/visionmedia/debug.git"
|
||||
},
|
||||
"description": "small debugging utility",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"log",
|
||||
"debugger"
|
||||
],
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
"Nathan Rajlich <nathan@tootallnate.net> (http://n8.io)",
|
||||
"Andrew Rhyne <rhyneandrew@gmail.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "9.0.3",
|
||||
"chai": "^3.5.0",
|
||||
"concurrently": "^3.1.0",
|
||||
"coveralls": "^2.11.15",
|
||||
"eslint": "^3.12.1",
|
||||
"istanbul": "^0.4.5",
|
||||
"karma": "^1.3.0",
|
||||
"karma-chai": "^0.1.0",
|
||||
"karma-mocha": "^1.3.0",
|
||||
"karma-phantomjs-launcher": "^1.0.2",
|
||||
"karma-sinon": "^1.0.5",
|
||||
"mocha": "^3.2.0",
|
||||
"mocha-lcov-reporter": "^1.2.0",
|
||||
"rimraf": "^2.5.4",
|
||||
"sinon": "^1.17.6",
|
||||
"sinon-chai": "^2.8.0"
|
||||
},
|
||||
"main": "./src/index.js",
|
||||
"browser": "./src/browser.js",
|
||||
"component": {
|
||||
"scripts": {
|
||||
"debug/index.js": "browser.js",
|
||||
"debug/debug.js": "debug.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
37
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/body-parser/node_modules/ms/package.json
generated
vendored
Normal file
37
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/body-parser/node_modules/ms/package.json
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "ms",
|
||||
"version": "2.0.0",
|
||||
"description": "Tiny milisecond conversion utility",
|
||||
"repository": "zeit/ms",
|
||||
"main": "./index",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"lint": "eslint lib/* bin/*",
|
||||
"test": "mocha tests.js"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"npm run lint",
|
||||
"prettier --single-quote --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"eslint": "3.19.0",
|
||||
"expect.js": "0.3.1",
|
||||
"husky": "0.13.3",
|
||||
"lint-staged": "3.4.1",
|
||||
"mocha": "3.4.1"
|
||||
}
|
||||
}
|
||||
52
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/body-parser/package.json
generated
vendored
Normal file
52
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/body-parser/package.json
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "body-parser",
|
||||
"description": "Node.js body parsing middleware",
|
||||
"version": "1.18.3",
|
||||
"contributors": [
|
||||
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": "expressjs/body-parser",
|
||||
"dependencies": {
|
||||
"bytes": "3.0.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "~1.6.3",
|
||||
"iconv-lite": "0.4.23",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.5.2",
|
||||
"raw-body": "2.3.3",
|
||||
"type-is": "~1.6.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "4.19.1",
|
||||
"eslint-config-standard": "11.0.0",
|
||||
"eslint-plugin-import": "2.11.0",
|
||||
"eslint-plugin-markdown": "1.0.0-beta.6",
|
||||
"eslint-plugin-node": "6.0.1",
|
||||
"eslint-plugin-promise": "3.7.0",
|
||||
"eslint-plugin-standard": "3.1.0",
|
||||
"istanbul": "0.4.5",
|
||||
"methods": "1.1.2",
|
||||
"mocha": "2.5.3",
|
||||
"safe-buffer": "5.1.2",
|
||||
"supertest": "1.1.0"
|
||||
},
|
||||
"files": [
|
||||
"lib/",
|
||||
"LICENSE",
|
||||
"HISTORY.md",
|
||||
"index.js"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --plugin markdown --ext js,md .",
|
||||
"test": "mocha --require test/support/env --reporter spec --check-leaks --bail test/",
|
||||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/",
|
||||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/"
|
||||
}
|
||||
}
|
||||
49
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/express/node_modules/debug/package.json
generated
vendored
Normal file
49
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/express/node_modules/debug/package.json
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "debug",
|
||||
"version": "2.6.9",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/visionmedia/debug.git"
|
||||
},
|
||||
"description": "small debugging utility",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"log",
|
||||
"debugger"
|
||||
],
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
"Nathan Rajlich <nathan@tootallnate.net> (http://n8.io)",
|
||||
"Andrew Rhyne <rhyneandrew@gmail.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "9.0.3",
|
||||
"chai": "^3.5.0",
|
||||
"concurrently": "^3.1.0",
|
||||
"coveralls": "^2.11.15",
|
||||
"eslint": "^3.12.1",
|
||||
"istanbul": "^0.4.5",
|
||||
"karma": "^1.3.0",
|
||||
"karma-chai": "^0.1.0",
|
||||
"karma-mocha": "^1.3.0",
|
||||
"karma-phantomjs-launcher": "^1.0.2",
|
||||
"karma-sinon": "^1.0.5",
|
||||
"mocha": "^3.2.0",
|
||||
"mocha-lcov-reporter": "^1.2.0",
|
||||
"rimraf": "^2.5.4",
|
||||
"sinon": "^1.17.6",
|
||||
"sinon-chai": "^2.8.0"
|
||||
},
|
||||
"main": "./src/index.js",
|
||||
"browser": "./src/browser.js",
|
||||
"component": {
|
||||
"scripts": {
|
||||
"debug/index.js": "browser.js",
|
||||
"debug/debug.js": "debug.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
37
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/express/node_modules/ms/package.json
generated
vendored
Normal file
37
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/express/node_modules/ms/package.json
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "ms",
|
||||
"version": "2.0.0",
|
||||
"description": "Tiny milisecond conversion utility",
|
||||
"repository": "zeit/ms",
|
||||
"main": "./index",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"lint": "eslint lib/* bin/*",
|
||||
"test": "mocha tests.js"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"npm run lint",
|
||||
"prettier --single-quote --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"eslint": "3.19.0",
|
||||
"expect.js": "0.3.1",
|
||||
"husky": "0.13.3",
|
||||
"lint-staged": "3.4.1",
|
||||
"mocha": "3.4.1"
|
||||
}
|
||||
}
|
||||
98
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/express/package.json
generated
vendored
Normal file
98
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/express/package.json
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"name": "express",
|
||||
"description": "Fast, unopinionated, minimalist web framework",
|
||||
"version": "4.16.4",
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
"Aaron Heckmann <aaron.heckmann+github@gmail.com>",
|
||||
"Ciaran Jessup <ciaranj@gmail.com>",
|
||||
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||
"Guillermo Rauch <rauchg@gmail.com>",
|
||||
"Jonathan Ong <me@jongleberry.com>",
|
||||
"Roman Shtylman <shtylman+expressjs@gmail.com>",
|
||||
"Young Jae Sim <hanul@hanul.me>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": "expressjs/express",
|
||||
"homepage": "http://expressjs.com/",
|
||||
"keywords": [
|
||||
"express",
|
||||
"framework",
|
||||
"sinatra",
|
||||
"web",
|
||||
"rest",
|
||||
"restful",
|
||||
"router",
|
||||
"app",
|
||||
"api"
|
||||
],
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.5",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.18.3",
|
||||
"content-disposition": "0.5.2",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.3.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "1.1.1",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.4",
|
||||
"qs": "6.5.2",
|
||||
"range-parser": "~1.2.0",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.16.2",
|
||||
"serve-static": "1.13.2",
|
||||
"setprototypeof": "1.1.0",
|
||||
"statuses": "~1.4.0",
|
||||
"type-is": "~1.6.16",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"after": "0.8.2",
|
||||
"connect-redis": "3.4.0",
|
||||
"cookie-parser": "~1.4.3",
|
||||
"cookie-session": "1.3.2",
|
||||
"ejs": "2.6.1",
|
||||
"eslint": "2.13.1",
|
||||
"express-session": "1.15.6",
|
||||
"hbs": "4.0.1",
|
||||
"istanbul": "0.4.5",
|
||||
"marked": "0.5.1",
|
||||
"method-override": "3.0.0",
|
||||
"mocha": "5.2.0",
|
||||
"morgan": "1.9.1",
|
||||
"multiparty": "4.2.1",
|
||||
"pbkdf2-password": "1.2.1",
|
||||
"should": "13.2.3",
|
||||
"supertest": "3.3.0",
|
||||
"vhost": "~3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"History.md",
|
||||
"Readme.md",
|
||||
"index.js",
|
||||
"lib/"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/",
|
||||
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/",
|
||||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
|
||||
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"
|
||||
}
|
||||
}
|
||||
37
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/ms/package.json
generated
vendored
Normal file
37
pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/ms/package.json
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "ms",
|
||||
"version": "2.1.1",
|
||||
"description": "Tiny millisecond conversion utility",
|
||||
"repository": "zeit/ms",
|
||||
"main": "./index",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"lint": "eslint lib/* bin/*",
|
||||
"test": "mocha tests.js"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"npm run lint",
|
||||
"prettier --single-quote --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"eslint": "4.12.1",
|
||||
"expect.js": "0.3.1",
|
||||
"husky": "0.14.3",
|
||||
"lint-staged": "5.0.0",
|
||||
"mocha": "4.0.1"
|
||||
}
|
||||
}
|
||||
12
pkg/fanal/analyzer/language/nodejs/npm/testdata/no-node_modules/package-lock.json
generated
vendored
Normal file
12
pkg/fanal/analyzer/language/nodejs/npm/testdata/no-node_modules/package-lock.json
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ const (
|
||||
|
||||
MavenPom = "pom.xml"
|
||||
|
||||
NpmPkg = "package.json"
|
||||
NpmPkgLock = "package-lock.json"
|
||||
YarnLock = "yarn.lock"
|
||||
PnpmLock = "pnpm-lock.yaml"
|
||||
|
||||
Reference in New Issue
Block a user