Author: fanningpj
Date: Sun Jul  5 23:16:17 2026
New Revision: 1935919

Log:
replace invalid xml chars in element content in Saver. Thanks to aizu-m. This 
closes #74

Modified:
   xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/store/Saver.java
   xmlbeans/trunk/src/test/java/misc/checkin/SaveOptimizeForSpeedTest.java

Modified: xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/store/Saver.java
==============================================================================
--- xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/store/Saver.java      
Sun Jul  5 20:10:03 2026        (r1935918)
+++ xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/store/Saver.java      
Sun Jul  5 23:16:17 2026        (r1935919)
@@ -2118,6 +2118,10 @@ abstract class Saver {
             int index = 0;
             for (int i = 0; i < bufLimit; i++) {
                 char c = _buf[i];
+                if (isBadChar(c)) {
+                    _buf[i] = '?';
+                    c = '?';
+                }
                 switch (c) {
                     case '<':
                         emit(_buf, index, i - index);

Modified: 
xmlbeans/trunk/src/test/java/misc/checkin/SaveOptimizeForSpeedTest.java
==============================================================================
--- xmlbeans/trunk/src/test/java/misc/checkin/SaveOptimizeForSpeedTest.java     
Sun Jul  5 20:10:03 2026        (r1935918)
+++ xmlbeans/trunk/src/test/java/misc/checkin/SaveOptimizeForSpeedTest.java     
Sun Jul  5 23:16:17 2026        (r1935919)
@@ -99,6 +99,23 @@ public class SaveOptimizeForSpeedTest {
     }
 
     @Test
+    void testBadCharInText() throws Exception {
+        // an invalid XML 1.0 character (a C0 control) in element content. The
+        // default saver replaces it with '?'; the speed path emitted it raw,
+        // producing output that is not well-formed.
+        XmlObject o = XmlObject.Factory.parse("<root/>");
+        try (XmlCursor cur = o.newCursor()) {
+            cur.toFirstChild();
+            cur.toFirstContentToken();
+            cur.insertChars("a\u0001b");
+        }
+        String out = saveForSpeed(o);
+        assertFalse(out.indexOf('\u0001') >= 0);
+        // before the fix the raw control char makes this a fatal parse error
+        XmlObject.Factory.parse(out);
+    }
+
+    @Test
     void testProcInstTerminatorAcrossChunkBoundary() throws Exception {
         // a '?>' that straddles the 512-char chunk boundary: '?' is the last 
char
         // of the first chunk, '>' the first char of the second. The per-chunk


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

Reply via email to