You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2026/08/20 14:45:39 UTC

(poi-xmlbeans) branch trunk updated: reject negative UTF length in LongUTFDataInputStream.readLongUTF (#93)

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

pjfanning pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi-xmlbeans.git


The following commit(s) were added to refs/heads/trunk by this push:
     new e27f97b1 reject negative UTF length in LongUTFDataInputStream.readLongUTF (#93)
e27f97b1 is described below

commit e27f97b10e770df365cd2d983a14a965e456c978
Author: aizu-m <ai...@gmail.com>
AuthorDate: Thu Aug 20 20:15:34 2026 +0530

    reject negative UTF length in LongUTFDataInputStream.readLongUTF (#93)
    
    reject negative UTF length in readLongUTF
---
 .../xmlbeans/impl/util/LongUTFDataInputStream.java |  3 +
 .../impl/util/LongUTFDataInputStreamTest.java      | 66 ++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git a/src/main/java/org/apache/xmlbeans/impl/util/LongUTFDataInputStream.java b/src/main/java/org/apache/xmlbeans/impl/util/LongUTFDataInputStream.java
index 2c7e95f6..ae7a46fc 100644
--- a/src/main/java/org/apache/xmlbeans/impl/util/LongUTFDataInputStream.java
+++ b/src/main/java/org/apache/xmlbeans/impl/util/LongUTFDataInputStream.java
@@ -49,6 +49,9 @@ public class LongUTFDataInputStream extends DataInputStream {
 
     public String readLongUTF() throws IOException {
         final int utfLen = readUnsignedShortOrInt();
+        if (utfLen < 0) {
+            throw new UTFDataFormatException("invalid UTF length: " + utfLen);
+        }
         StringBuilder sb = new StringBuilder(utfLen/2);
         final byte[] bytearr = new byte[4096];
 
diff --git a/src/test/java/org/apache/xmlbeans/impl/util/LongUTFDataInputStreamTest.java b/src/test/java/org/apache/xmlbeans/impl/util/LongUTFDataInputStreamTest.java
new file mode 100644
index 00000000..685340f7
--- /dev/null
+++ b/src/test/java/org/apache/xmlbeans/impl/util/LongUTFDataInputStreamTest.java
@@ -0,0 +1,66 @@
+/*   Copyright 2026 The Apache Software Foundation
+ *
+ *   Licensed 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.xmlbeans.impl.util;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UTFDataFormatException;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class LongUTFDataInputStreamTest {
+
+    @Test
+    void readLongUTFRejectsNegativeLength() {
+        // readUnsignedShortOrInt() falls back to a signed readInt() for the
+        // 0xfffe marker, so the length can be negative. A crafted .xsb string
+        // pool entry whose length prefix is FF FE followed by a negative int
+        // must surface as a UTFDataFormatException, not NegativeArraySizeException.
+        byte[] bytes = { (byte) 0xFF, (byte) 0xFE, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFE };
+        LongUTFDataInputStream in = new LongUTFDataInputStream(new ByteArrayInputStream(bytes));
+        assertThrows(UTFDataFormatException.class, in::readLongUTF);
+    }
+
+    @Test
+    void readLongUTFRoundTripsShortString() throws IOException {
+        assertEquals("hello", roundTrip("hello"));
+    }
+
+    @Test
+    void readLongUTFRoundTripsLargeStringViaEscape() throws IOException {
+        // a value whose UTF byte length exceeds 65534 is written with the 0xfffe
+        // escape and a full int length, so the length reaches readLongUTF through
+        // readInt - the negative-length guard must not reject a valid large length
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < 70000; i++) {
+            sb.append('a');
+        }
+        String big = sb.toString();
+        assertEquals(big, roundTrip(big));
+    }
+
+    private static String roundTrip(String s) throws IOException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        LongUTFDataOutputStream out = new LongUTFDataOutputStream(bos);
+        out.writeLongUTF(s);
+        out.flush();
+        LongUTFDataInputStream in = new LongUTFDataInputStream(new ByteArrayInputStream(bos.toByteArray()));
+        return in.readLongUTF();
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org