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

pvillard31 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 d8aae33a981 NIFI-16146 Fixed FileUtils sanitization of UTF-16 in 
filenames (#11478)
d8aae33a981 is described below

commit d8aae33a981a85dcf96cc06eeec38b6cbd3e2768
Author: David Handermann <[email protected]>
AuthorDate: Mon Jul 27 09:50:14 2026 -0500

    NIFI-16146 Fixed FileUtils sanitization of UTF-16 in filenames (#11478)
---
 .../src/main/java/org/apache/nifi/util/file/FileUtils.java | 12 ++++++++----
 .../test/java/org/apache/nifi/util/file/FileUtilsTest.java | 14 ++++++++++++++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git 
a/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/util/file/FileUtils.java
 
b/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/util/file/FileUtils.java
index 3babb6e4118..cb6ac762274 100644
--- 
a/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/util/file/FileUtils.java
+++ 
b/nifi-commons/nifi-utils/src/main/java/org/apache/nifi/util/file/FileUtils.java
@@ -586,6 +586,8 @@ public class FileUtils {
     private static final int[] INVALID_CHARS = {34, 60, 62, 124, 0, 1, 2, 3, 
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
             16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 
58, 42, 63, 92, 47};
 
+    private static final char REPLACEMENT_CHARACTER = '_';
+
     static {
         Arrays.sort(INVALID_CHARS);
     }
@@ -597,7 +599,7 @@ public class FileUtils {
      * @param filename The filename to clean
      * @return sanitized filename
      */
-    public static String getSanitizedFilename(String filename) {
+    public static String getSanitizedFilename(final String filename) {
         if (filename == null) {
             return null;
         }
@@ -605,15 +607,17 @@ public class FileUtils {
             return "";
         }
 
-        final int codePointCount = filename.codePointCount(0, 
filename.length());
+        final int filenameLength = filename.length();
         final StringBuilder cleanName = new StringBuilder();
-        for (int i = 0; i < codePointCount; i++) {
+        for (int i = 0; i < filenameLength;) {
             final int c = filename.codePointAt(i);
             if (Arrays.binarySearch(INVALID_CHARS, c) < 0) {
                 cleanName.appendCodePoint(c);
             } else {
-                cleanName.append('_');
+                cleanName.append(REPLACEMENT_CHARACTER);
             }
+            // Advance index based on character count to handle UTF-16
+            i += Character.charCount(c);
         }
         return cleanName.toString();
     }
diff --git 
a/nifi-commons/nifi-utils/src/test/java/org/apache/nifi/util/file/FileUtilsTest.java
 
b/nifi-commons/nifi-utils/src/test/java/org/apache/nifi/util/file/FileUtilsTest.java
index 3fddac7ff62..017d89a5f26 100644
--- 
a/nifi-commons/nifi-utils/src/test/java/org/apache/nifi/util/file/FileUtilsTest.java
+++ 
b/nifi-commons/nifi-utils/src/test/java/org/apache/nifi/util/file/FileUtilsTest.java
@@ -50,4 +50,18 @@ class FileUtilsTest {
         assertEquals("report...", FileUtils.getSanitizedFilename("report..."));
         assertEquals(".env", FileUtils.getSanitizedFilename(".env"));
     }
+
+    @Test
+    void testGetSanitizedFilenamePreservesSupplementaryCodePoints() {
+        // U+1F4C4 PAGE FACING UP - encoded as a UTF-16 surrogate pair
+        final int pageFacingUpCharacter = 0x1F4C4;
+        final String pageFacingUp = new 
String(Character.toChars(pageFacingUpCharacter));
+
+        final String complexFilename = "a" + pageFacingUp + "b";
+        assertEquals(complexFilename, 
FileUtils.getSanitizedFilename(complexFilename));
+
+        // Test standard character replacements
+        assertEquals(pageFacingUp + "_file.txt", 
FileUtils.getSanitizedFilename(pageFacingUp + "/file.txt"));
+        assertEquals("report " + pageFacingUp + ".txt", 
FileUtils.getSanitizedFilename("report " + pageFacingUp + ".txt"));
+    }
 }

Reply via email to