Skip to content

Commit 8a472f5

Browse files
committed
1 parent 0407d05 commit 8a472f5

File tree

2 files changed

+135
-88
lines changed

2 files changed

+135
-88
lines changed

src/main/java/org/codehaus/plexus/util/xml/pull/MXSerializer.java

+92-88
Original file line numberDiff line numberDiff line change
@@ -853,95 +853,36 @@ public void flush() throws IOException {
853853
// --- utility methods
854854

855855
protected void writeAttributeValue(String value, Writer out) throws IOException {
856-
// .[apostrophe and <, & escaped],
857-
final char quot = attributeUseApostrophe ? '\'' : '"';
858-
final String quotEntity = attributeUseApostrophe ? "&apos;" : "&quot;";
859-
860-
int pos = 0;
861-
for (int i = 0; i < value.length(); i++) {
862-
char ch = value.charAt(i);
863-
if (ch == '&') {
864-
if (i > pos) out.write(value.substring(pos, i));
865-
out.write("&amp;");
866-
pos = i + 1;
867-
}
868-
if (ch == '<') {
869-
if (i > pos) out.write(value.substring(pos, i));
870-
out.write("&lt;");
871-
pos = i + 1;
872-
} else if (ch == quot) {
873-
if (i > pos) out.write(value.substring(pos, i));
874-
out.write(quotEntity);
875-
pos = i + 1;
876-
} else if (ch < 32) {
877-
// in XML 1.0 only legal character are #x9 | #xA | #xD
878-
// and they must be escaped otherwise in attribute value they are normalized to spaces
879-
if (ch == 13 || ch == 10 || ch == 9) {
880-
if (i > pos) out.write(value.substring(pos, i));
881-
out.write("&#");
882-
out.write(Integer.toString(ch));
883-
out.write(';');
884-
pos = i + 1;
885-
} else {
886-
throw new IllegalStateException(
887-
"character " + Integer.toString(ch) + " is not allowed in output" + getLocation());
888-
// in XML 1.1 legal are [#x1-#xD7FF]
889-
// if(ch > 0) {
890-
// if(i > pos) out.write(text.substring(pos, i));
891-
// out.write("&#");
892-
// out.write(Integer.toString(ch));
893-
// out.write(';');
894-
// pos = i + 1;
895-
// } else {
896-
// throw new IllegalStateException(
897-
// "character zero is not allowed in XML 1.1 output"+getLocation());
898-
// }
899-
}
900-
}
901-
}
902-
if (pos > 0) {
903-
out.write(value.substring(pos));
904-
} else {
905-
out.write(value); // this is shortcut to the most common case
906-
}
907-
}
908-
909-
protected void writeElementContent(String text, Writer out) throws IOException {
910-
// escape '<', '&', ']]>', <32 if necessary
911-
int pos = 0;
912-
for (int i = 0; i < text.length(); i++) {
913-
// TODO: check if doing char[] text.getChars() would be faster than getCharAt(i) ...
914-
char ch = text.charAt(i);
915-
if (ch == ']') {
916-
if (seenBracket) {
917-
seenBracketBracket = true;
918-
} else {
919-
seenBracket = true;
920-
}
921-
} else {
856+
if (value != null) {
857+
// .[apostrophe and <, & escaped],
858+
final char quot = attributeUseApostrophe ? '\'' : '"';
859+
final String quotEntity = attributeUseApostrophe ? "&apos;" : "&quot;";
860+
861+
int pos = 0;
862+
for (int i = 0; i < value.length(); i++) {
863+
char ch = value.charAt(i);
922864
if (ch == '&') {
923-
if (i > pos) out.write(text.substring(pos, i));
865+
if (i > pos) out.write(value.substring(pos, i));
924866
out.write("&amp;");
925867
pos = i + 1;
926-
} else if (ch == '<') {
927-
if (i > pos) out.write(text.substring(pos, i));
868+
}
869+
if (ch == '<') {
870+
if (i > pos) out.write(value.substring(pos, i));
928871
out.write("&lt;");
929872
pos = i + 1;
930-
} else if (seenBracketBracket && ch == '>') {
931-
if (i > pos) out.write(text.substring(pos, i));
932-
out.write("&gt;");
873+
} else if (ch == quot) {
874+
if (i > pos) out.write(value.substring(pos, i));
875+
out.write(quotEntity);
933876
pos = i + 1;
934877
} else if (ch < 32) {
935878
// in XML 1.0 only legal character are #x9 | #xA | #xD
936-
if (ch == 9 || ch == 10 || ch == 13) {
937-
// pass through
938-
939-
// } else if(ch == 13) { //escape
940-
// if(i > pos) out.write(text.substring(pos, i));
941-
// out.write("&#");
942-
// out.write(Integer.toString(ch));
943-
// out.write(';');
944-
// pos = i + 1;
879+
// and they must be escaped otherwise in attribute value they are normalized to spaces
880+
if (ch == 13 || ch == 10 || ch == 9) {
881+
if (i > pos) out.write(value.substring(pos, i));
882+
out.write("&#");
883+
out.write(Integer.toString(ch));
884+
out.write(';');
885+
pos = i + 1;
945886
} else {
946887
throw new IllegalStateException(
947888
"character " + Integer.toString(ch) + " is not allowed in output" + getLocation());
@@ -958,15 +899,78 @@ protected void writeElementContent(String text, Writer out) throws IOException {
958899
// }
959900
}
960901
}
961-
if (seenBracket) {
962-
seenBracketBracket = seenBracket = false;
963-
}
902+
}
903+
if (pos > 0) {
904+
out.write(value.substring(pos));
905+
} else {
906+
out.write(value); // this is shortcut to the most common case
964907
}
965908
}
966-
if (pos > 0) {
967-
out.write(text.substring(pos));
968-
} else {
969-
out.write(text); // this is shortcut to the most common case
909+
}
910+
911+
protected void writeElementContent(String text, Writer out) throws IOException {
912+
if (text != null) {
913+
// escape '<', '&', ']]>', <32 if necessary
914+
int pos = 0;
915+
for (int i = 0; i < text.length(); i++) {
916+
// TODO: check if doing char[] text.getChars() would be faster than getCharAt(i) ...
917+
char ch = text.charAt(i);
918+
if (ch == ']') {
919+
if (seenBracket) {
920+
seenBracketBracket = true;
921+
} else {
922+
if (ch == '&') {
923+
if (i > pos)
924+
out.write(text.substring(pos, i));
925+
out.write("&amp;");
926+
pos = i + 1;
927+
} else if (ch == '<') {
928+
if (i > pos)
929+
out.write(text.substring(pos, i));
930+
out.write("&lt;");
931+
pos = i + 1;
932+
} else if (seenBracketBracket && ch == '>') {
933+
if (i > pos)
934+
out.write(text.substring(pos, i));
935+
out.write("&gt;");
936+
pos = i + 1;
937+
} else if (ch < 32) {
938+
// in XML 1.0 only legal character are #x9 | #xA | #xD
939+
if (ch == 9 || ch == 10 || ch == 13) {
940+
// pass through
941+
942+
// } else if(ch == 13) { //escape
943+
// if(i > pos) out.write(text.substring(pos, i));
944+
// out.write("&#");
945+
// out.write(Integer.toString(ch));
946+
// out.write(';');
947+
// pos = i + 1;
948+
} else {
949+
throw new IllegalStateException("character " + Integer.toString(ch) + " is not allowed in output" + getLocation());
950+
// in XML 1.1 legal are [#x1-#xD7FF]
951+
// if(ch > 0) {
952+
// if(i > pos) out.write(text.substring(pos, i));
953+
// out.write("&#");
954+
// out.write(Integer.toString(ch));
955+
// out.write(';');
956+
// pos = i + 1;
957+
// } else {
958+
// throw new IllegalStateException(
959+
// "character zero is not allowed in XML 1.1 output"+getLocation());
960+
// }
961+
}
962+
}
963+
if (seenBracket) {
964+
seenBracketBracket = seenBracket = false;
965+
}
966+
}
967+
}
968+
if (pos > 0) {
969+
out.write(text.substring(pos));
970+
} else {
971+
out.write(text); // this is shortcut to the most common case
972+
}
973+
}
970974
}
971975
}
972976

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.codehaus.plexus.util.xml.pull;
20+
21+
import java.io.IOException;
22+
import java.io.StringWriter;
23+
24+
import org.junit.jupiter.api.Test;
25+
26+
/**
27+
* Tests {@link MXSerializer}.
28+
*/
29+
public class MXSerializerTest {
30+
31+
/**
32+
* Tests MJAVADOC-793.
33+
*/
34+
@Test
35+
public void testNpe() throws IOException {
36+
// should be no-ops
37+
new MXSerializer().writeElementContent(null, null);
38+
new MXSerializer().writeAttributeValue(null, null);
39+
final StringWriter stringWriter = new StringWriter();
40+
new MXSerializer().writeElementContent(null, stringWriter);
41+
new MXSerializer().writeAttributeValue(null, stringWriter);
42+
}
43+
}

0 commit comments

Comments
 (0)