diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb index b0c57e958a9..80beb3d226d 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb @@ -205,11 +205,16 @@ def lerna_packages @lerna_packages ||= fetch_lerna_packages end + # rubocop:disable Metrics/PerceivedComplexity def path_dependencies(fetched_files) package_json_files = [] unfetchable_deps = [] path_dependency_details(fetched_files).each do |name, path| + # This happens with relative paths in the package-lock. Skipping it since it results + # in /package.json which is outside of the project directory. + next if path == "file:" + path = path.gsub(PATH_DEPENDENCY_CLEAN_REGEX, "") raise PathDependenciesNotReachable, "#{name} at #{path}" if path.start_with?("/") @@ -238,6 +243,7 @@ def path_dependencies(fetched_files) package_json_files.tap { |fs| fs.each { |f| f.support_file = true } } end + # rubocop:enable Metrics/PerceivedComplexity def path_dependency_details(fetched_files) package_json_path_deps = [] diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/file_fetcher_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_fetcher_spec.rb index aab9493d0f7..91aa470710c 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/file_fetcher_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_fetcher_spec.rb @@ -97,6 +97,37 @@ end end + context "that has a blank file: in the package-lock" do + before do + stub_request(:get, File.join(url, "package.json?ref=sha")). + with(headers: { "Authorization" => "token token" }). + to_return( + status: 200, + body: fixture_to_response("projects/npm8/path_dependency_blank_file", "package.json"), + headers: json_header + ) + stub_request(:get, File.join(url, "package-lock.json?ref=sha")). + with(headers: { "Authorization" => "token token" }). + to_return( + status: 200, + body: fixture_to_response("projects/npm8/path_dependency_blank_file", "package-lock.json"), + headers: json_header + ) + stub_request(:get, File.join(url, "another/package.json?ref=sha")). + with(headers: { "Authorization" => "token token" }). + to_return( + status: 200, + body: fixture_to_response("projects/npm8/path_dependency_blank_file/another", "package.json"), + headers: json_header + ) + end + + it "does not have a /package.json" do + expect(file_fetcher_instance.files.map(&:name)). + to eq(%w(package.json package-lock.json another/package.json)) + end + end + context "with a .npmrc file" do before do stub_request(:get, url + "?ref=sha"). @@ -1591,12 +1622,6 @@ end context "with no .npmrc but package-lock.json contains a custom registry" do - def fixture_to_response(dir, file) - JSON.dump({ - "content" => Base64.encode64(fixture(dir, file)) - }) - end - before do allow(file_fetcher_instance).to receive(:commit).and_return("sha") @@ -1626,3 +1651,7 @@ def fixture_to_response(dir, file) end end end + +def fixture_to_response(dir, file) + JSON.dump({ "content" => Base64.encode64(fixture(dir, file)) }) +end diff --git a/npm_and_yarn/spec/fixtures/projects/npm8/path_dependency_blank_file/another/package.json b/npm_and_yarn/spec/fixtures/projects/npm8/path_dependency_blank_file/another/package.json new file mode 100644 index 00000000000..f1834a44c88 --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/npm8/path_dependency_blank_file/another/package.json @@ -0,0 +1,14 @@ +{ + "name": "another", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "right-pad": "^1.0.0" + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/npm8/path_dependency_blank_file/package-lock.json b/npm_and_yarn/spec/fixtures/projects/npm8/path_dependency_blank_file/package-lock.json new file mode 100644 index 00000000000..1a13b1a48a2 --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/npm8/path_dependency_blank_file/package-lock.json @@ -0,0 +1,95 @@ +{ + "name": "npm-eacces", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "npm-eacces", + "version": "1.0.0", + "license": "ISC", + "workspaces": [ + ".", + "./", + "another" + ], + "dependencies": { + "another": "^1.0.0", + "left-pad": "1.2" + } + }, + "another": { + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "right-pad": "^1.0.0" + } + }, + "node_modules/another": { + "resolved": "another", + "link": true + }, + "node_modules/left-pad": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.2.0.tgz", + "integrity": "sha512-OQadpCyFCT/VLniZQgym8d3/ofIJtuZyw2ibsVeIUOexKgW/osn8+mMFJbwGMPeDC4GnLzD8q115WPCDx4YRWg==", + "deprecated": "use String.prototype.padStart()" + }, + "node_modules/npm-eacces": { + "resolved": "", + "link": true + }, + "node_modules/right-pad": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", + "integrity": "sha512-bYBjgxmkvTAfgIYy328fmkwhp39v8lwVgWhhrzxPV3yHtcSqyYKe9/XOhvW48UFjATg3VuJbpsp5822ACNvkmw==", + "engines": { + "node": ">= 0.10" + } + } + }, + "dependencies": { + "another": { + "version": "file:another", + "requires": { + "right-pad": "^1.0.0" + } + }, + "left-pad": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.2.0.tgz", + "integrity": "sha512-OQadpCyFCT/VLniZQgym8d3/ofIJtuZyw2ibsVeIUOexKgW/osn8+mMFJbwGMPeDC4GnLzD8q115WPCDx4YRWg==" + }, + "npm-eacces": { + "version": "file:", + "requires": { + "another": "file:another", + "left-pad": "1.2", + "npm-eacces": "file:" + }, + "dependencies": { + "another": { + "version": "file:another", + "requires": { + "right-pad": "^1.0.0" + } + }, + "left-pad": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.2.0.tgz", + "integrity": "sha512-OQadpCyFCT/VLniZQgym8d3/ofIJtuZyw2ibsVeIUOexKgW/osn8+mMFJbwGMPeDC4GnLzD8q115WPCDx4YRWg==" + }, + "right-pad": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", + "integrity": "sha512-bYBjgxmkvTAfgIYy328fmkwhp39v8lwVgWhhrzxPV3yHtcSqyYKe9/XOhvW48UFjATg3VuJbpsp5822ACNvkmw==" + } + } + }, + "right-pad": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", + "integrity": "sha512-bYBjgxmkvTAfgIYy328fmkwhp39v8lwVgWhhrzxPV3yHtcSqyYKe9/XOhvW48UFjATg3VuJbpsp5822ACNvkmw==" + } + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/npm8/path_dependency_blank_file/package.json b/npm_and_yarn/spec/fixtures/projects/npm8/path_dependency_blank_file/package.json new file mode 100644 index 00000000000..b91d1ad92e0 --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/npm8/path_dependency_blank_file/package.json @@ -0,0 +1,28 @@ +{ + "name": "npm-eacces", + "version": "1.0.0", + "description": "", + "main": "index.js", + "workspaces": [ + ".", + "./", + "another" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/dsp-testing/npm-eacces.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/dsp-testing/npm-eacces/issues" + }, + "homepage": "https://github.com/dsp-testing/npm-eacces#readme", + "dependencies": { + "another": "^1.0.0", + "left-pad": "1.2" + } +}