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

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


The following commit(s) were added to refs/heads/main by this push:
     new d10f4291 fix: Image type recognition failure in FileTypeUtils (#812)
d10f4291 is described below

commit d10f429110bb05d126c83f0d90c96b2f579400c3
Author: Bengbengbalabalabeng 
<[email protected]>
AuthorDate: Fri Feb 27 10:07:46 2026 +0800

    fix: Image type recognition failure in FileTypeUtils (#812)
    
    * fix: Image type recognition failure in FileTypeUtils
    
    * fix: use longest-prefix-first matching for magic numbers
    
    * test: add sample image files for FileTypeUtils tests
    
    ---------
    
    Co-authored-by: ian zhang <[email protected]>
    Co-authored-by: DeleiGuo <[email protected]>
---
 .../org/apache/fesod/sheet/util/FileTypeUtils.java |  25 +++-
 .../apache/fesod/sheet/util/FileTypeUtilsTest.java | 150 +++++++++++++++++++++
 .../src/test/resources/images/fesod-logo-jpeg.jpeg | Bin 0 -> 22682 bytes
 .../src/test/resources/images/fesod-logo-png.png   | Bin 0 -> 15935 bytes
 .../src/test/resources/images/fesod-logo-svg.svg   |   1 +
 5 files changed, 171 insertions(+), 5 deletions(-)

diff --git 
a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/FileTypeUtils.java 
b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/FileTypeUtils.java
index 33b47f91..ec9f0a70 100644
--- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/FileTypeUtils.java
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/FileTypeUtils.java
@@ -19,6 +19,7 @@
 
 package org.apache.fesod.sheet.util;
 
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
 import org.apache.fesod.sheet.metadata.data.ImageData;
@@ -33,6 +34,7 @@ public class FileTypeUtils {
     private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', 
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
     };
     private static final int IMAGE_TYPE_MARK_LENGTH = 28;
+    private static final int IMAGE_TYPE_MARK_MIN_LENGTH = 3;
 
     private static final Map<String, ImageData.ImageType> FILE_TYPE_MAP;
 
@@ -43,8 +45,8 @@ public class FileTypeUtils {
 
     static {
         FILE_TYPE_MAP = new HashMap<>();
-        FILE_TYPE_MAP.put("ffd8ff", ImageData.ImageType.PICTURE_TYPE_JPEG);
         FILE_TYPE_MAP.put("89504e47", ImageData.ImageType.PICTURE_TYPE_PNG);
+        FILE_TYPE_MAP.put("ffd8ff", ImageData.ImageType.PICTURE_TYPE_JPEG);
     }
 
     public static int getImageTypeFormat(byte[] image) {
@@ -56,12 +58,25 @@ public class FileTypeUtils {
     }
 
     public static ImageData.ImageType getImageType(byte[] image) {
-        if (image == null || image.length <= IMAGE_TYPE_MARK_LENGTH) {
+        if (image == null || image.length < IMAGE_TYPE_MARK_MIN_LENGTH) {
             return null;
         }
-        byte[] typeMarkByte = new byte[IMAGE_TYPE_MARK_LENGTH];
-        System.arraycopy(image, 0, typeMarkByte, 0, IMAGE_TYPE_MARK_LENGTH);
-        return FILE_TYPE_MAP.get(encodeHexStr(typeMarkByte));
+        int lengthToCopy = Math.min(image.length, IMAGE_TYPE_MARK_LENGTH);
+        byte[] typeMarkByte = new byte[lengthToCopy];
+        System.arraycopy(image, 0, typeMarkByte, 0, lengthToCopy);
+
+        String hexString = encodeHexStr(typeMarkByte);
+
+        return FILE_TYPE_MAP.entrySet().stream()
+                .sorted(longestPrefixFirst())
+                .filter(e -> hexString.startsWith(e.getKey()))
+                .findFirst()
+                .map(Map.Entry::getValue)
+                .orElse(null);
+    }
+
+    private static Comparator<Map.Entry<String, ImageData.ImageType>> 
longestPrefixFirst() {
+        return (a, b) -> b.getKey().length() - a.getKey().length();
     }
 
     private static String encodeHexStr(byte[] data) {
diff --git 
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/FileTypeUtilsTest.java 
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/FileTypeUtilsTest.java
new file mode 100644
index 00000000..fcd84924
--- /dev/null
+++ 
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/FileTypeUtilsTest.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fesod.sheet.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import org.apache.fesod.sheet.metadata.data.ImageData;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+
+/**
+ * Tests {@link FileTypeUtils}
+ */
+class FileTypeUtilsTest {
+
+    private byte[] realJpeg;
+    private byte[] realPng;
+    private byte[] realSvg;
+
+    @BeforeEach
+    void setup() throws Exception {
+        realJpeg = loadImage("fesod-logo-jpeg.jpeg");
+        realPng = loadImage("fesod-logo-png.png");
+        realSvg = loadImage("fesod-logo-svg.svg");
+    }
+
+    private byte[] loadImage(String filename) throws IOException {
+        try (InputStream is = 
getClass().getClassLoader().getResourceAsStream("images" + File.separator + 
filename); ) {
+            Assertions.assertNotNull(is);
+
+            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+            byte[] data = new byte[4096];
+            int n;
+            while ((n = is.read(data, 0, data.length)) != -1) {
+                buffer.write(data, 0, n);
+            }
+            return buffer.toByteArray();
+        }
+    }
+
+    @ParameterizedTest
+    @NullAndEmptySource
+    void test_getImageType_NullOrEmpty(byte[] input) {
+        Assertions.assertNull(FileTypeUtils.getImageType(input));
+    }
+
+    @Test
+    void test_getImageType_tooShort() {
+        byte[] input = new byte[] {(byte) 0x00, (byte) 0x01};
+        Assertions.assertNull(FileTypeUtils.getImageType(input));
+    }
+
+    @Test
+    void test_getImageType_safeCopy() {
+        // JPEG
+        byte[] input = new byte[10];
+        input[0] = (byte) 0xFF;
+        input[1] = (byte) 0xD8;
+        input[2] = (byte) 0xFF;
+        input[3] = (byte) 0xE0;
+
+        Assertions.assertDoesNotThrow(() -> {
+            ImageData.ImageType type = FileTypeUtils.getImageType(input);
+            Assertions.assertEquals(ImageData.ImageType.PICTURE_TYPE_JPEG, 
type);
+        });
+    }
+
+    @Test
+    void test_getImageType_JPEG() {
+        // JPEG: ffd8ff
+        byte[] jpeg = new byte[30];
+        jpeg[0] = (byte) 0xFF;
+        jpeg[1] = (byte) 0xD8;
+        jpeg[2] = (byte) 0xFF;
+
+        Assertions.assertEquals(ImageData.ImageType.PICTURE_TYPE_JPEG, 
FileTypeUtils.getImageType(jpeg));
+        Assertions.assertEquals(ImageData.ImageType.PICTURE_TYPE_JPEG, 
FileTypeUtils.getImageType(realJpeg));
+    }
+
+    @Test
+    void test_getImageType_PNG() {
+        // PNG: 89504e47
+        byte[] png = new byte[30];
+        png[0] = (byte) 0x89;
+        png[1] = (byte) 0x50;
+        png[2] = (byte) 0x4E;
+        png[3] = (byte) 0x47;
+
+        Assertions.assertEquals(ImageData.ImageType.PICTURE_TYPE_PNG, 
FileTypeUtils.getImageType(png));
+        Assertions.assertEquals(ImageData.ImageType.PICTURE_TYPE_PNG, 
FileTypeUtils.getImageType(realPng));
+    }
+
+    @Test
+    void test_getImageType_unknown() {
+        byte[] unknown = new byte[30];
+        Assertions.assertNull(FileTypeUtils.getImageType(unknown));
+        Assertions.assertNull(FileTypeUtils.getImageType(realSvg));
+    }
+
+    @Test
+    void test_getImageTypeFormat_success() {
+        byte[] jpeg = new byte[30];
+        jpeg[0] = (byte) 0xFF;
+        jpeg[1] = (byte) 0xD8;
+        jpeg[2] = (byte) 0xFF;
+
+        int typeOfJpeg = FileTypeUtils.getImageTypeFormat(jpeg);
+        int typeOfRealJpeg = FileTypeUtils.getImageTypeFormat(realJpeg);
+        int typeOfPng = FileTypeUtils.getImageTypeFormat(realPng);
+        
Assertions.assertEquals(ImageData.ImageType.PICTURE_TYPE_JPEG.getValue(), 
typeOfJpeg);
+        
Assertions.assertEquals(ImageData.ImageType.PICTURE_TYPE_JPEG.getValue(), 
typeOfRealJpeg);
+        
Assertions.assertEquals(ImageData.ImageType.PICTURE_TYPE_PNG.getValue(), 
typeOfPng);
+    }
+
+    @Test
+    void test_getImageTypeFormat_default() {
+        byte[] unknown = new byte[30];
+
+        int result = FileTypeUtils.getImageTypeFormat(unknown);
+
+        Assertions.assertEquals(FileTypeUtils.defaultImageType.getValue(), 
result);
+    }
+
+    @Test
+    void test_DefaultConfig() {
+        Assertions.assertEquals(ImageData.ImageType.PICTURE_TYPE_PNG, 
FileTypeUtils.defaultImageType);
+    }
+}
diff --git a/fesod-sheet/src/test/resources/images/fesod-logo-jpeg.jpeg 
b/fesod-sheet/src/test/resources/images/fesod-logo-jpeg.jpeg
new file mode 100644
index 00000000..39a983eb
Binary files /dev/null and 
b/fesod-sheet/src/test/resources/images/fesod-logo-jpeg.jpeg differ
diff --git a/fesod-sheet/src/test/resources/images/fesod-logo-png.png 
b/fesod-sheet/src/test/resources/images/fesod-logo-png.png
new file mode 100644
index 00000000..65d71cbc
Binary files /dev/null and 
b/fesod-sheet/src/test/resources/images/fesod-logo-png.png differ
diff --git a/fesod-sheet/src/test/resources/images/fesod-logo-svg.svg 
b/fesod-sheet/src/test/resources/images/fesod-logo-svg.svg
new file mode 100644
index 00000000..6c080ff8
--- /dev/null
+++ b/fesod-sheet/src/test/resources/images/fesod-logo-svg.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; width="222" height="220" viewBox="0 
0 222 220" fill="none"><path     fill="#14824B"  d="M113.324 163.939L81.7664 
132.382L81.7664 132.382C85.415 136.03 85.4151 141.946 81.7665 145.595L81.6 
145.761L66.2449 161.116C62.066 165.295 62.066 172.071 66.245 176.25L83.6291 
193.634C87.8081 197.813 94.5836 197.813 98.7625 193.634L113.324 179.073C117.503 
174.894 117.503 168.118 113.324 163.939Z"></path><path   fill-rul [...]
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to