This is an automated email from the ASF dual-hosted git repository.

exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 08e25ae003 NIFI-14759 Handle out-of-order File Entries in NarUnpacker 
(#10270)
08e25ae003 is described below

commit 08e25ae0034c03503de7ff961f706c023659ee0d
Author: Pierre Villard <[email protected]>
AuthorDate: Thu Sep 4 18:28:54 2025 +0200

    NIFI-14759 Handle out-of-order File Entries in NarUnpacker (#10270)
    
    Signed-off-by: David Handermann <[email protected]>
---
 .../java/org/apache/nifi/nar/NarUnpackerTest.java  | 36 ++++++++++++++++++++++
 .../main/java/org/apache/nifi/nar/NarUnpacker.java |  6 ++++
 2 files changed, 42 insertions(+)

diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
index db11aa854b..d62cf4dc01 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
@@ -23,8 +23,10 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.io.TempDir;
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -38,6 +40,8 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
 import java.util.stream.Stream;
 
 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
@@ -194,6 +198,38 @@ public class NarUnpackerTest {
         assertTrue(extensionMapping.isEmpty());
     }
 
+    @Test
+    public void testUnpackNarHandlesManifestBeforeMetaInfDirectory(@TempDir 
final Path tempDir) throws IOException {
+        // Create a minimal NAR with problematic entry order: MANIFEST first, 
then META-INF/ directory
+        final File narFile = tempDir.resolve("bad-order.nar").toFile();
+        try (FileOutputStream fos = new FileOutputStream(narFile);
+             JarOutputStream jos = new JarOutputStream(fos)) {
+            // MANIFEST first (without prior META-INF/ dir entry)
+            final JarEntry manifestEntry = new 
JarEntry("META-INF/MANIFEST.MF");
+            jos.putNextEntry(manifestEntry);
+            final byte[] manifestBytes = (
+                    "Manifest-Version: 1.0\n" +
+                    "NAR-Group: org.example\n" +
+                    "NAR-Id: test-nar\n" +
+                    "NAR-Version: 1.0.0\n\n"
+            ).getBytes(StandardCharsets.UTF_8);
+            jos.write(manifestBytes);
+            jos.closeEntry();
+
+            // META-INF/ directory entry added after
+            final JarEntry metaInfDir = new JarEntry("META-INF/");
+            jos.putNextEntry(metaInfDir);
+            jos.closeEntry();
+        }
+
+        final File baseWorkingDir = tempDir.resolve("work").toFile();
+
+        // Should unpack successfully despite directory entry order
+        final File unpackedDir = NarUnpacker.unpackNar(narFile, 
baseWorkingDir, true, NarUnpackMode.UNPACK_INDIVIDUAL_JARS);
+        final File manifestOut = new File(unpackedDir, "META-INF/MANIFEST.MF");
+        assertTrue(manifestOut.isFile(), "Manifest should be unpacked even 
when META-INF/ entry comes later");
+    }
+
     private NiFiProperties loadSpecifiedProperties(final Map<String, String> 
others) {
         String filePath;
         try {
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarUnpacker.java
 
b/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarUnpacker.java
index b9881d6f86..18ff8cf78e 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarUnpacker.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarUnpacker.java
@@ -595,6 +595,12 @@ public final class NarUnpacker {
      *             if the file could not be created.
      */
     private static void makeFile(final InputStream inputStream, final File 
file) throws IOException {
+        // Ensure parent directories exist to handle archives where directory 
entries
+        // appear after file entries (e.g., after jarsigner has reordered 
entries)
+        final File parent = file.getParentFile();
+        if (parent != null) {
+            Files.createDirectories(parent.toPath());
+        }
         try (final InputStream in = inputStream;
                 final FileOutputStream fos = new FileOutputStream(file)) {
             byte[] bytes = new byte[65536];

Reply via email to