Skip to content

Commit 19dd8a2

Browse files
committed
add tests verifying invalid sequence; also add tests to verify cases where the pairs are at the edges or anywhere in the text
1 parent 98d5dfc commit 19dd8a2

File tree

1 file changed

+109
-16
lines changed

1 file changed

+109
-16
lines changed

test/jaxp/javax/xml/jaxp/unittest/transform/JDK8207760.java

Lines changed: 109 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -93,6 +93,14 @@ public class JDK8207760 {
9393
"\n" +
9494
"</xsl:stylesheet>";
9595

96+
final String xsl8349699 = """
97+
<?xml version="1.0" encoding="UTF-8"?>
98+
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
99+
<xsl:output encoding="UTF-8" method="text" />
100+
<xsl:template match="/"><xsl:apply-templates select="node()" /></xsl:template>
101+
</xsl:stylesheet>
102+
""";
103+
96104
@DataProvider(name = "xsls")
97105
public Object[][] getDataBug8207760_cdata() {
98106
return new Object[][]{
@@ -101,32 +109,117 @@ public Object[][] getDataBug8207760_cdata() {
101109
};
102110
}
103111

112+
/*
113+
* Data for verifying the patch for JDK8349699
114+
* @see testBug8349699
115+
*/
116+
@DataProvider(name = "surrogatePair")
117+
public Object[][] getDataFor8349699() {
118+
return new Object[][]{
119+
// a surrogate pair in an XML element placed anywhere in a string
120+
{getXML(1024, 1024, "<b>\uD835\uDF00</b>"), getString(1024, 1024, "\uD835\uDF00")},
121+
{getXML(1023, 1023, "<b>\uD835\uDF00</b>"), getString(1023, 1023, "\uD835\uDF00")},
122+
{getXML(1023,0, "<b>\uD835\uDF00</b>"), getString(1023,0, "\uD835\uDF00")},
123+
{getXML(1023,120, "<b>\uD835\uDF00</b>"), getString(1023,120, "\uD835\uDF00")},
124+
// this is the original test as demonstrated in the bug report
125+
{getXML(1017,1017, "\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uD835\uDF00</b>\uD835\uDF00"),
126+
getString(1017,1017, "\uD835\uDF03\uD835\uDF00\uD835\uDF00\uD835\uDF00\uD835\uDF00")},
127+
{getXML(1017,0, "\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uD835\uDF00</b>\uD835\uDF00"),
128+
getString(1017,0, "\uD835\uDF03\uD835\uDF00\uD835\uDF00\uD835\uDF00\uD835\uDF00")},
129+
{getXML(1017,120, "\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uD835\uDF00</b>\uD835\uDF00"),
130+
getString(1017,120, "\uD835\uDF03\uD835\uDF00\uD835\uDF00\uD835\uDF00\uD835\uDF00")},
131+
};
132+
}
133+
134+
/*
135+
* Data for verifying the patch for JDK8349699
136+
* @see testBug8349699N
137+
*/
138+
@DataProvider(name = "invalidSurrogatePair")
139+
public Object[][] getDataFor8349699N() {
140+
return new Object[][]{
141+
// invalid pair: high/high
142+
{getXML(1024, 1024, "<b>\uD835\uD835</b>")},
143+
{getXML(1023, 1023, "<b>\uD835\uD835</b>")},
144+
{getXML(1023,0, "<b>\uD835\uD835</b>")},
145+
{getXML(1023,120, "<b>\uD835\uD835</b>")},
146+
// invalid pair: low/low
147+
{getXML(1024, 1024, "<b>\uDF00\uDF00</b>")},
148+
{getXML(1023, 1023, "<b>\uDF00\uDF00</b>")},
149+
{getXML(1023,0, "<b>\uDF00\uDF00</b>")},
150+
{getXML(1023,120, "<b>\uDF00\uDF00</b>")},
151+
// invalid pair in the original test string
152+
{getXML(1017,1017, "\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uD835\uD835</b>\uD835\uDF00")},
153+
{getXML(1017,0, "\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uD835\uD835</b>\uD835\uDF00")},
154+
{getXML(1017,120, "\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uD835\uD835</b>\uD835\uDF00")},
155+
{getXML(1017,1017, "\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uDF00\uDF00</b>\uD835\uDF00")},
156+
{getXML(1017,0, "\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uDF00\uDF00</b>\uD835\uDF00")},
157+
{getXML(1017,120, "\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uDF00\uDF00</b>\uD835\uDF00")},
158+
};
159+
}
160+
104161
/*
105162
* @bug 8349699
106163
* Verifies that a surrogate pair at the edge of a buffer is properly handled
107164
* when serializing into a Character section.
108165
*/
109-
@Test
110-
public final void testBug8349699() throws Exception {
111-
String xs = "x".repeat(1017);
112-
String expected = xs + "\uD835\uDF03\uD835\uDF00\uD835\uDF00\uD835\uDF00\uD835\uDF00";
113-
String xml = "<?xml version=\"1.0\" ?><a>{1017x}\uD835\uDF03\uD835\uDF00\uD835\uDF00<b>\uD835\uDF00</b>\uD835\uDF00</a> "
114-
.replace("{1017x}", xs);
115-
String xsl = """
116-
<?xml version="1.0" encoding="UTF-8"?>
117-
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
118-
<xsl:output encoding="UTF-8" method="text" />
119-
<xsl:template match="/"><xsl:apply-templates select="node()" /></xsl:template>
120-
</xsl:stylesheet>
121-
""";
122-
166+
@Test(dataProvider = "surrogatePair")
167+
public final void testBug8349699(String xml, String expected) throws Exception {
123168
Transformer t = createTransformerFromInputstream(
124-
new ByteArrayInputStream(xsl.getBytes(StandardCharsets.UTF_8)));
169+
new ByteArrayInputStream(xsl8349699.getBytes(StandardCharsets.UTF_8)));
125170
StringWriter sw = new StringWriter();
126171
t.transform(new StreamSource(new StringReader(xml)), new StreamResult(sw));
127172
Assert.assertEquals(sw.toString(), expected);
128173
}
129174

175+
/*
176+
* @bug 8349699
177+
* Verifies that invalid surrogate pairs are caught.
178+
*/
179+
@Test(dataProvider = "invalidSurrogatePair")
180+
public final void testBug8349699N(String xml) throws Exception {
181+
Assert.assertThrows(TransformerException.class, () -> {
182+
Transformer t = createTransformerFromInputstream(
183+
new ByteArrayInputStream(xsl8349699.getBytes(StandardCharsets.UTF_8)));
184+
StringWriter sw = new StringWriter();
185+
t.transform(new StreamSource(new StringReader(xml)), new StreamResult(sw));
186+
});
187+
}
188+
189+
/**
190+
* Returns an XML with the input string inserted in a text of length 'len' at
191+
* the position 'pos'.
192+
* @param len the length of the text to be placed in the XML
193+
* @param pos the position at which the input string will be inserted into the text
194+
* @param input the input string
195+
* @return an XML
196+
*/
197+
private String getXML(int len, int pos, String input) {
198+
StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" ?><a>");
199+
sb.append(getString(len, pos, input));
200+
sb.append("</a>");
201+
return sb.toString();
202+
}
203+
204+
/**
205+
* Returns a text string with the input string inserted at the specified position.
206+
* @param len the length of the text to be returned
207+
* @param pos the position at which the input string will be inserted into the text
208+
* @param input the input string
209+
* @return a text string
210+
*/
211+
private String getString(int len, int pos, String input) {
212+
StringBuilder sb = new StringBuilder();
213+
if (pos == 0) {
214+
sb.append(input).append("x".repeat(len));
215+
} else if (pos == len) {
216+
sb.append("x".repeat(len)).append(input);
217+
} else {
218+
sb.append("x".repeat(pos)).append(input).append("x".repeat(len - pos));
219+
}
220+
return sb.toString();
221+
}
222+
130223
/*
131224
* @bug 8207760
132225
* Verifies that a surrogate pair at the edge of a buffer is properly handled

0 commit comments

Comments
 (0)