From 36996b280e2df73986118398327a63df105feb09 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 1 Feb 2023 07:38:18 -0600 Subject: [PATCH] fix: throw exception if pyproject.toml is found resolves #4995 --- .../analyzer/PoetryAnalyzer.java | 38 ++++++++++++++----- .../analyzer/PoetryAnalyzerTest.java | 7 ++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzer.java index b95c66cdee1..e94478f8812 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzer.java @@ -35,10 +35,9 @@ import org.owasp.dependencycheck.utils.Settings; import com.moandjiezana.toml.Toml; -import org.apache.commons.lang3.StringUtils; +import java.io.File; import org.owasp.dependencycheck.data.nvd.ecosystem.Ecosystem; import org.owasp.dependencycheck.dependency.naming.GenericIdentifier; -import org.owasp.dependencycheck.dependency.naming.Identifier; import org.owasp.dependencycheck.dependency.naming.PurlIdentifier; import org.owasp.dependencycheck.utils.Checksum; import org.slf4j.Logger; @@ -69,12 +68,15 @@ public class PoetryAnalyzer extends AbstractFileTypeAnalyzer { * Lock file name. */ private static final String POETRY_LOCK = "poetry.lock"; - + /** + * Poetry project file. + */ + private static final String PYPROJECT_TOML = "pyproject.toml"; /** * The file filter for poetry.lock */ private static final FileFilter POETRY_LOCK_FILTER = FileFilterBuilder.newInstance() - .addFilenames(POETRY_LOCK) + .addFilenames(POETRY_LOCK, PYPROJECT_TOML) .build(); /** @@ -145,6 +147,13 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An //do not report on the build file itself engine.removeDependency(dependency); + if (PYPROJECT_TOML.equals(dependency.getActualFile().getName())) { + File parentPath = dependency.getActualFile().getParentFile(); + ensureLock(parentPath); + //exit as we can't analyze pyproject.toml - insufficient version information + return; + } + final Toml result = new Toml().read(dependency.getActualFile()); final List projectsLocks = result.getTables("package"); if (projectsLocks == null) { @@ -161,12 +170,12 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An d.setVersion(version); try { - final PackageURL purl = PackageURLBuilder.aPackageURL() - .withType("pypi") - .withName(name) - .withVersion(version) - .build(); - d.addSoftwareIdentifier(new PurlIdentifier(purl, Confidence.HIGHEST)); + final PackageURL purl = PackageURLBuilder.aPackageURL() + .withType("pypi") + .withName(name) + .withVersion(version) + .build(); + d.addSoftwareIdentifier(new PurlIdentifier(purl, Confidence.HIGHEST)); } catch (MalformedPackageURLException ex) { LOGGER.debug("Unable to build package url for pypi", ex); d.addSoftwareIdentifier(new GenericIdentifier("pypi:" + name + "@" + version, Confidence.HIGH)); @@ -185,4 +194,13 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An engine.addDependency(d); }); } + + private void ensureLock(File parent) throws AnalysisException { + File lock = new File(parent, POETRY_LOCK); + File requirements = new File(parent, "requirements.txt"); + boolean found = lock.isFile() || requirements.isFile(); + if (!found) { + throw new AnalysisException("Python `pyproject.toml` found and there is not a `poetry.lock` or `requirements.txt` - analysis will be incomplete"); + } + } } diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzerTest.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzerTest.java index 75360edb4d6..643d9fd79b3 100644 --- a/core/src/test/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzerTest.java +++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/PoetryAnalyzerTest.java @@ -72,4 +72,11 @@ public void testPoetryLock() throws AnalysisException { } assertTrue("Expeced to find PyYAML", found); } + + @Test(expected = AnalysisException.class) + public void testPyprojectToml() throws AnalysisException { + final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "python-myproject-toml/pyproject.toml")); + //causes an exception. + analyzer.analyze(result, engine); + } }