Author: fanningpj
Date: Mon Jun 29 13:18:52 2026
New Revision: 1935709
Log:
uard short handle string in XsbReader.readHandle. Thanks to aizu-m. This closes
#73
Added:
xmlbeans/trunk/src/test/java/org/apache/xmlbeans/impl/schema/XsbReaderHandleTest.java
Modified:
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/schema/XsbReader.java
Modified:
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/schema/XsbReader.java
==============================================================================
--- xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/schema/XsbReader.java
Mon Jun 29 12:45:04 2026 (r1935708)
+++ xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/schema/XsbReader.java
Mon Jun 29 13:18:52 2026 (r1935709)
@@ -437,10 +437,20 @@ class XsbReader {
return null;
}
+ if (handle.isEmpty()) {
+ throw new SchemaTypeLoaderException("Cannot resolve handle " +
handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE);
+ }
+
if (handle.charAt(0) != '_') {
return typeSystem.getTypePool().refForHandle(handle);
}
+ // every '_'-prefixed handle is a 4-char tag ("_BI_", "_XT_", ...)
plus a
+ // payload; charAt(2) and forPretty(handle, 4) below read past a
shorter one
+ if (handle.length() < 4) {
+ throw new SchemaTypeLoaderException("Cannot resolve handle " +
handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE);
+ }
+
switch (handle.charAt(2)) {
case 'I': // _BI_ - built-in schema type system
SchemaType st = (SchemaType)
BuiltinSchemaTypeSystem.get().resolveHandle(handle);
Added:
xmlbeans/trunk/src/test/java/org/apache/xmlbeans/impl/schema/XsbReaderHandleTest.java
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++
xmlbeans/trunk/src/test/java/org/apache/xmlbeans/impl/schema/XsbReaderHandleTest.java
Mon Jun 29 13:18:52 2026 (r1935709)
@@ -0,0 +1,67 @@
+/* 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.xmlbeans.impl.schema;
+
+import org.apache.xmlbeans.SchemaTypeLoaderException;
+import org.apache.xmlbeans.impl.util.LongUTFDataInputStream;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.lang.reflect.Field;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class XsbReaderHandleTest {
+
+ // Builds an XsbReader whose next readString() returns the given component
+ // handle, exactly as a crafted/corrupt .xsb would supply it.
+ private static XsbReader readerForHandle(String handle) throws Exception {
+ XsbReader reader = new XsbReader(new SchemaTypeSystemImpl("test"),
"h");
+
+ Field poolF = XsbReader.class.getDeclaredField("_stringPool");
+ poolF.setAccessible(true);
+ SchemaTypeSystemImpl.StringPool pool =
(SchemaTypeSystemImpl.StringPool) poolF.get(reader);
+ int code = pool.codeForString(handle);
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(bos);
+ dos.writeShort(code); // readString -> readUnsignedShortOrInt ->
stringForCode(code)
+ dos.flush();
+
+ Field inputF = XsbReader.class.getDeclaredField("_input");
+ inputF.setAccessible(true);
+ inputF.set(reader, new LongUTFDataInputStream(new
ByteArrayInputStream(bos.toByteArray())));
+
+ return reader;
+ }
+
+ @Test
+ void rejectsEmptyHandle() throws Exception {
+ // an empty handle used to throw StringIndexOutOfBoundsException at
handle.charAt(0)
+ XsbReader reader = readerForHandle("");
+ assertThrows(SchemaTypeLoaderException.class, reader::readHandle);
+ }
+
+ @Test
+ void rejectsShortUnderscoreHandle() throws Exception {
+ // "_X" starts with '_' but is too short for handle.charAt(2)
+ XsbReader reader = readerForHandle("_X");
+ assertThrows(SchemaTypeLoaderException.class, reader::readHandle);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]