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