From b1fb691d20a93bfc4e570b8068814ff7f0eed2ba Mon Sep 17 00:00:00 2001 From: itsmehotpants Date: Fri, 24 Jul 2026 20:01:46 +0000 Subject: [PATCH] Fix NPEs in SuffixMapping, SingleTargetMapping, and URLLocation - SuffixMapping#getTargetFiles: guard against null source/sourceSuffix before calling String#endsWith, returning an empty result set instead of throwing NullPointerException. - SingleTargetMapping#getTargetFiles: same guard for the same endsWith(null) NPE pattern. - URLLocation#initFile: fall back to default temp-file prefix/suffix ("url" / ".tmp") when the caller passes null, instead of letting Files.createTempFile(null, null) throw NullPointerException. Adds regression tests for each case, matching the existing test style. Fixes #93, Fixes #94, Fixes #95 --- .../maven/shared/io/location/URLLocation.java | 5 +- .../io/scan/mapping/SingleTargetMapping.java | 2 +- .../shared/io/scan/mapping/SuffixMapping.java | 4 ++ .../shared/io/location/URLLocationTest.java | 12 +++++ .../io/scan/mapping/SuffixMappingTest.java | 48 +++++++++++++++++++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/maven/shared/io/location/URLLocation.java b/src/main/java/org/apache/maven/shared/io/location/URLLocation.java index ae9d645..e327356 100644 --- a/src/main/java/org/apache/maven/shared/io/location/URLLocation.java +++ b/src/main/java/org/apache/maven/shared/io/location/URLLocation.java @@ -58,7 +58,10 @@ public URLLocation( /** {@inheritDoc} */ protected void initFile() throws IOException { if (unsafeGetFile() == null) { - File tempFile = Files.createTempFile(tempFilePrefix, tempFileSuffix).toFile(); + String prefix = tempFilePrefix == null ? "url" : tempFilePrefix; + String suffix = tempFileSuffix == null ? ".tmp" : tempFileSuffix; + + File tempFile = Files.createTempFile(prefix, suffix).toFile(); if (tempFileDeleteOnExit) { tempFile.deleteOnExit(); diff --git a/src/main/java/org/apache/maven/shared/io/scan/mapping/SingleTargetMapping.java b/src/main/java/org/apache/maven/shared/io/scan/mapping/SingleTargetMapping.java index 0ac1d11..8b7c699 100644 --- a/src/main/java/org/apache/maven/shared/io/scan/mapping/SingleTargetMapping.java +++ b/src/main/java/org/apache/maven/shared/io/scan/mapping/SingleTargetMapping.java @@ -47,7 +47,7 @@ public SingleTargetMapping(String sourceSuffix, String outputFile) { /** {@inheritDoc} */ public Set getTargetFiles(File targetDir, String source) throws InclusionScanException { - if (!source.endsWith(sourceSuffix)) { + if (source == null || sourceSuffix == null || !source.endsWith(sourceSuffix)) { return Collections.emptySet(); } diff --git a/src/main/java/org/apache/maven/shared/io/scan/mapping/SuffixMapping.java b/src/main/java/org/apache/maven/shared/io/scan/mapping/SuffixMapping.java index 2b1ecc5..a882dc2 100644 --- a/src/main/java/org/apache/maven/shared/io/scan/mapping/SuffixMapping.java +++ b/src/main/java/org/apache/maven/shared/io/scan/mapping/SuffixMapping.java @@ -56,6 +56,10 @@ public SuffixMapping(String sourceSuffix, Set targetSuffixes) { public Set getTargetFiles(File targetDir, String source) { Set targetFiles = new HashSet<>(); + if (source == null || sourceSuffix == null) { + return targetFiles; + } + if (source.endsWith(sourceSuffix)) { String base = source.substring(0, source.length() - sourceSuffix.length()); diff --git a/src/test/java/org/apache/maven/shared/io/location/URLLocationTest.java b/src/test/java/org/apache/maven/shared/io/location/URLLocationTest.java index 62e3db8..801b868 100644 --- a/src/test/java/org/apache/maven/shared/io/location/URLLocationTest.java +++ b/src/test/java/org/apache/maven/shared/io/location/URLLocationTest.java @@ -77,4 +77,16 @@ void shouldTransferFromTempFileThenRead() throws Exception { assertEquals(testStr, new String(buffer, "US-ASCII")); } + + @Test + void shouldNotThrowNpeWhenTempFilePrefixAndSuffixAreNull() throws Exception { + File f = Files.createTempFile("url-location.", ".test").toFile(); + f.deleteOnExit(); + + URL url = f.toURL(); + + URLLocation location = new URLLocation(url, f.getAbsolutePath(), null, null, true); + + assertNotNull(location.getFile()); + } } diff --git a/src/test/java/org/apache/maven/shared/io/scan/mapping/SuffixMappingTest.java b/src/test/java/org/apache/maven/shared/io/scan/mapping/SuffixMappingTest.java index c376ad0..757471d 100644 --- a/src/test/java/org/apache/maven/shared/io/scan/mapping/SuffixMappingTest.java +++ b/src/test/java/org/apache/maven/shared/io/scan/mapping/SuffixMappingTest.java @@ -97,6 +97,30 @@ void shouldReturnNoTargetFilesWhenSourceFileHasWrongSuffix() throws Exception { assertTrue(results.isEmpty(), "Returned wrong number of target files."); } + @Test + void shouldReturnNoTargetFilesWhenSourceIsNull() throws Exception { + File basedir = new File("."); + + SuffixMapping mapping = new SuffixMapping(".java", ".class"); + + Set results = mapping.getTargetFiles(basedir, null); + + assertTrue(results.isEmpty(), "Returned wrong number of target files."); + } + + @Test + void shouldReturnNoTargetFilesWhenSourceSuffixIsNull() throws Exception { + String base = "path/to/file"; + + File basedir = new File("."); + + SuffixMapping mapping = new SuffixMapping(null, ".class"); + + Set results = mapping.getTargetFiles(basedir, base + ".java"); + + assertTrue(results.isEmpty(), "Returned wrong number of target files."); + } + @Test void singleTargetMapper() throws Exception { String base = "path/to/file"; @@ -113,4 +137,28 @@ void singleTargetMapper() throws Exception { assertEquals(1, results.size()); } + + @Test + void singleTargetMapperShouldReturnNoTargetFilesWhenSourceIsNull() throws Exception { + File basedir = new File("target/"); + + SingleTargetMapping mapping = new SingleTargetMapping(".cs", "/foo"); + + Set results = mapping.getTargetFiles(basedir, null); + + assertTrue(results.isEmpty()); + } + + @Test + void singleTargetMapperShouldReturnNoTargetFilesWhenSourceSuffixIsNull() throws Exception { + String base = "path/to/file"; + + File basedir = new File("target/"); + + SingleTargetMapping mapping = new SingleTargetMapping(null, "/foo"); + + Set results = mapping.getTargetFiles(basedir, base + ".cs"); + + assertTrue(results.isEmpty()); + } }