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

markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
     new c417394f02 Review "Do not swallow exceptions when loading translation 
property..."
c417394f02 is described below

commit c417394f023f3c6a4169a6368992f04aac6623bf
Author: Mark Thomas <[email protected]>
AuthorDate: Fri Nov 6 18:08:20 2026 +0000

    Review "Do not swallow exceptions when loading translation property..."
    
    Report mal-formed UTF-8 encoding and escaped
---
 .../apache/tomcat/buildutil/translate/Utils.java   | 22 ++++++++++-
 .../tomcat/buildutil/translate/TestUtils.java      | 44 ++++++++++++++++++++++
 2 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/tomcat/buildutil/translate/Utils.java 
b/java/org/apache/tomcat/buildutil/translate/Utils.java
index eddc4c7cc4..ca48792011 100644
--- a/java/org/apache/tomcat/buildutil/translate/Utils.java
+++ b/java/org/apache/tomcat/buildutil/translate/Utils.java
@@ -24,6 +24,9 @@ import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.util.Arrays;
@@ -62,12 +65,27 @@ public class Utils {
     }
 
 
+    /**
+     * Loads a properties file that is encoded as UTF-8.
+     *
+     * @param f The file to load
+     *
+     * @return The properties in the file
+     *
+     * @throws IOException if the file cannot be read, is not valid UTF-8 or 
contains a malformed escape sequence. The
+     *                         message of the exception includes the name of 
the file.
+     */
     static Properties load(File f) throws IOException {
         Properties props = new Properties();
 
-        try (FileInputStream fis = new FileInputStream(f);
-                Reader r = new InputStreamReader(fis, StandardCharsets.UTF_8)) 
{
+        // Report invalid UTF-8 rather than silently replacing it
+        CharsetDecoder decoder = 
StandardCharsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.REPORT)
+                .onUnmappableCharacter(CodingErrorAction.REPORT);
+
+        try (FileInputStream fis = new FileInputStream(f); Reader r = new 
InputStreamReader(fis, decoder)) {
             props.load(r);
+        } catch (CharacterCodingException | IllegalArgumentException e) {
+            throw new IOException("Unable to load [" + f.getPath() + "]: " + 
e, e);
         }
         return props;
     }
diff --git a/test/org/apache/tomcat/buildutil/translate/TestUtils.java 
b/test/org/apache/tomcat/buildutil/translate/TestUtils.java
index d7b4175938..37122842ec 100644
--- a/test/org/apache/tomcat/buildutil/translate/TestUtils.java
+++ b/test/org/apache/tomcat/buildutil/translate/TestUtils.java
@@ -16,11 +16,22 @@
  */
 package org.apache.tomcat.buildutil.translate;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.Properties;
+
 import org.junit.Assert;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 
 public class TestUtils {
 
+    @Rule
+    public TemporaryFolder temp = new TemporaryFolder();
+
     @Test
     public void testFormatValue01() {
         // Import from POE
@@ -56,4 +67,37 @@ public class TestUtils {
         // Export from Tomcat
         Assert.assertEquals("line1\\n\\\n\\tline2\\n\\\n\\tline3", 
Utils.formatValueExport("line1\n\tline2\n\tline3"));
     }
+
+    @Test
+    public void testLoadValid() throws IOException {
+        File f = temp.newFile("valid.properties");
+        Files.write(f.toPath(), 
"key=caf\u00e9\n".getBytes(StandardCharsets.UTF_8));
+        Properties props = Utils.load(f);
+        Assert.assertEquals("caf\u00e9", props.getProperty("key"));
+    }
+
+    @Test
+    public void testLoadInvalidUtf8() throws IOException {
+        File f = temp.newFile("invalid-utf8.properties");
+        Files.write(f.toPath(), new byte[] { 'k', '=', (byte) 0xC3, (byte) 
0x28, '\n' });
+        try {
+            Utils.load(f);
+            Assert.fail("Invalid UTF-8 was accepted");
+        } catch (IOException e) {
+            Assert.assertTrue(e.getMessage(), 
e.getMessage().contains("invalid-utf8.properties"));
+        }
+    }
+
+    @Test
+    public void testLoadMalformedEscape() throws IOException {
+        File f = temp.newFile("bad-escape.properties");
+        Files.write(f.toPath(), 
"key=\\u12\n".getBytes(StandardCharsets.UTF_8));
+        try {
+            Utils.load(f);
+            Assert.fail("The malformed escape was accepted");
+        } catch (IOException e) {
+            Assert.assertTrue(e.getMessage(), 
e.getMessage().contains("bad-escape.properties"));
+            Assert.assertTrue(e.getCause() instanceof 
IllegalArgumentException);
+        }
+    }
 }


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

Reply via email to