Skip to content

Commit 363dca3

Browse files
authored
fix: #6819 handle invalid toml file (#7548)
2 parents ce651ca + d81df61 commit 363dca3

File tree

3 files changed

+158
-5
lines changed

3 files changed

+158
-5
lines changed

core/src/main/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzer.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
15-
*
16-
* Copyright (c) 2019 Nima Yahyazadeh. All Rights Reserved.
1715
*/
1816
package org.owasp.dependencycheck.analyzer;
1917

@@ -36,6 +34,8 @@
3634

3735
import com.moandjiezana.toml.Toml;
3836
import java.io.File;
37+
import java.util.Optional;
38+
3939
import org.owasp.dependencycheck.data.nvd.ecosystem.Ecosystem;
4040
import org.owasp.dependencycheck.dependency.naming.GenericIdentifier;
4141
import org.owasp.dependencycheck.dependency.naming.PurlIdentifier;
@@ -147,7 +147,12 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An
147147
//do not report on the build file itself
148148
engine.removeDependency(dependency);
149149

150-
final Toml result = new Toml().read(dependency.getActualFile());
150+
Optional<Toml> potentiallyParsedToml = parseDependencyFile(dependency);
151+
if (potentiallyParsedToml.isEmpty()) {
152+
LOGGER.warn("toml file skipped: {} could not be parsed", dependency.getActualFilePath());
153+
return;
154+
}
155+
final Toml result = potentiallyParsedToml.get();
151156
if (PYPROJECT_TOML.equals(dependency.getActualFile().getName())) {
152157
if (result.getTable("tool.poetry") == null) {
153158
LOGGER.debug("skipping {} as it does not contain `tool.poetry`", dependency.getDisplayFileName());
@@ -200,6 +205,30 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An
200205
});
201206
}
202207

208+
private Optional<Toml> parseDependencyFile(Dependency dependency) {
209+
try {
210+
Toml toml = new Toml().read(dependency.getActualFile());
211+
return Optional.of(toml);
212+
} catch (RuntimeException e) {
213+
Optional<String> unparsableFileErrorMessage = Optional.ofNullable(e.getCause())
214+
.filter(c -> c instanceof IllegalStateException)
215+
.map(Throwable::getMessage)
216+
.filter(PoetryAnalyzer::isInvalidKeyErrorMessage);
217+
218+
if (unparsableFileErrorMessage.isPresent()) {
219+
String message = String.format("Invalid toml file, cannot parse '%s'", dependency.getActualFile());
220+
LOGGER.debug(message, e);
221+
return Optional.empty();
222+
}
223+
224+
throw e;
225+
}
226+
}
227+
228+
private static boolean isInvalidKeyErrorMessage(String m) {
229+
return m.startsWith("Invalid key");
230+
}
231+
203232
private void ensureLock(File parent) throws AnalysisException {
204233
final File lock = new File(parent, POETRY_LOCK);
205234
final File requirements = new File(parent, "requirements.txt");

core/src/test/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzerTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
15-
*
16-
* Copyright (c) 2019 Nima Yahyazadeh. All Rights Reserved.
1715
*/
1816
package org.owasp.dependencycheck.analyzer;
1917

@@ -80,6 +78,13 @@ public void testPyprojectToml() throws AnalysisException {
8078
analyzer.analyze(result, engine);
8179
}
8280

81+
@Test
82+
public void testNodeGypToml() throws AnalysisException {
83+
final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "node-gyp-toml/pyproject.toml"));
84+
//returns with no error.
85+
analyzer.analyze(result, engine);
86+
}
87+
8388
@Test(expected = AnalysisException.class)
8489
public void testPoetryToml() throws AnalysisException {
8590
final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "python-poetry-toml/pyproject.toml"));
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "gyp-next"
7+
version = "0.16.1"
8+
authors = [
9+
{ name="Node.js contributors", email="[email protected]" },
10+
]
11+
description = "A fork of the GYP build system for use in the Node.js projects"
12+
readme = "README.md"
13+
license = { file="LICENSE" }
14+
requires-python = ">=3.8"
15+
# The Python module "packaging" is vendored in the "pylib/packaging" directory to support Python >= 3.12.
16+
# dependencies = ["packaging>=23.1"] # Uncomment this line if the vendored version is removed.
17+
classifiers = [
18+
"Development Status :: 3 - Alpha",
19+
"Environment :: Console",
20+
"Intended Audience :: Developers",
21+
"License :: OSI Approved :: BSD License",
22+
"Natural Language :: English",
23+
"Programming Language :: Python",
24+
"Programming Language :: Python :: 3",
25+
"Programming Language :: Python :: 3.8",
26+
"Programming Language :: Python :: 3.9",
27+
"Programming Language :: Python :: 3.10",
28+
"Programming Language :: Python :: 3.11",
29+
]
30+
31+
[project.optional-dependencies]
32+
dev = ["flake8", "ruff", "pytest"]
33+
34+
[project.scripts]
35+
gyp = "gyp:script_main"
36+
37+
[project.urls]
38+
"Homepage" = "https://github.com/nodejs/gyp-next"
39+
40+
[tool.ruff]
41+
lint.select = [
42+
"C4", # flake8-comprehensions
43+
"C90", # McCabe cyclomatic complexity
44+
"DTZ", # flake8-datetimez
45+
"E", # pycodestyle
46+
"F", # Pyflakes
47+
"G", # flake8-logging-format
48+
"ICN", # flake8-import-conventions
49+
"INT", # flake8-gettext
50+
"PL", # Pylint
51+
"PYI", # flake8-pyi
52+
"RSE", # flake8-raise
53+
"RUF", # Ruff-specific rules
54+
"T10", # flake8-debugger
55+
"TCH", # flake8-type-checking
56+
"TID", # flake8-tidy-imports
57+
"UP", # pyupgrade
58+
"W", # pycodestyle
59+
"YTT", # flake8-2020
60+
# "A", # flake8-builtins
61+
# "ANN", # flake8-annotations
62+
# "ARG", # flake8-unused-arguments
63+
# "B", # flake8-bugbear
64+
# "BLE", # flake8-blind-except
65+
# "COM", # flake8-commas
66+
# "D", # pydocstyle
67+
# "DJ", # flake8-django
68+
# "EM", # flake8-errmsg
69+
# "ERA", # eradicate
70+
# "EXE", # flake8-executable
71+
# "FBT", # flake8-boolean-trap
72+
# "I", # isort
73+
# "INP", # flake8-no-pep420
74+
# "ISC", # flake8-implicit-str-concat
75+
# "N", # pep8-naming
76+
# "NPY", # NumPy-specific rules
77+
# "PD", # pandas-vet
78+
# "PGH", # pygrep-hooks
79+
# "PIE", # flake8-pie
80+
# "PT", # flake8-pytest-style
81+
# "PTH", # flake8-use-pathlib
82+
# "Q", # flake8-quotes
83+
# "RET", # flake8-return
84+
# "S", # flake8-bandit
85+
# "SIM", # flake8-simplify
86+
# "SLF", # flake8-self
87+
# "T20", # flake8-print
88+
# "TRY", # tryceratops
89+
]
90+
lint.ignore = [
91+
"E721",
92+
"PLC1901",
93+
"PLR0402",
94+
"PLR1714",
95+
"PLR2004",
96+
"PLR5501",
97+
"PLW0603",
98+
"PLW2901",
99+
"PYI024",
100+
"RUF005",
101+
"RUF012",
102+
"UP031",
103+
]
104+
extend-exclude = ["pylib/packaging"]
105+
line-length = 88
106+
target-version = "py37"
107+
108+
[tool.ruff.lint.mccabe]
109+
max-complexity = 101
110+
111+
[tool.ruff.lint.pylint]
112+
max-args = 11
113+
max-branches = 108
114+
max-returns = 10
115+
max-statements = 286
116+
117+
[tool.setuptools]
118+
package-dir = {"" = "pylib"}
119+
packages = ["gyp", "gyp.generator"]

0 commit comments

Comments
 (0)