Merge branch '7.0.x'

This commit is contained in:
Sam Brannen
2026-09-04 15:14:36 +02:00
3 changed files with 44 additions and 11 deletions
@@ -190,7 +190,7 @@ abstract class AbstractXMLStreamReader implements XMLStreamReader {
@Override
public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) {
char[] source = getTextCharacters();
length = Math.min(length, source.length);
length = Math.min(length, source.length - sourceStart);
System.arraycopy(source, sourceStart, target, targetStart, length);
return length;
}
@@ -34,9 +34,11 @@ import javax.xml.stream.events.XMLEvent;
import org.jspecify.annotations.Nullable;
/**
* Implementation of the {@link javax.xml.stream.XMLStreamReader} interface that wraps a
* {@link XMLEventReader}. Useful because the StAX {@link javax.xml.stream.XMLInputFactory}
* allows one to create an event reader from a stream reader, but not vice-versa.
* Implementation of the {@link javax.xml.stream.XMLStreamReader} interface that wraps an
* {@link XMLEventReader}.
*
* <p>Useful because the StAX {@link javax.xml.stream.XMLInputFactory} allows one
* to create an event reader from a stream reader, but not vice-versa.
*
* @author Arjen Poutsma
* @since 3.0
@@ -21,13 +21,15 @@ import java.io.StringWriter;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.w3c.dom.Node;
import org.xmlunit.util.Predicate;
@@ -35,21 +37,24 @@ import org.springframework.core.testfixture.xml.XmlContent;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link XMLEventStreamReader}.
*/
class XMLEventStreamReaderTests {
private static final String XML =
"<?pi content?><root xmlns='namespace'><prefix:child xmlns:prefix='namespace2'>content</prefix:child></root>"
;
"<?pi content?><root xmlns='namespace'><prefix:child xmlns:prefix='namespace2'>content</prefix:child></root>";
private XMLEventStreamReader streamReader;
private final XMLEventStreamReader streamReader;
@BeforeEach
void createStreamReader() throws Exception {
XMLEventStreamReaderTests() throws Exception {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLEventReader eventReader = inputFactory.createXMLEventReader(new StringReader(XML));
streamReader = new XMLEventStreamReader(eventReader);
this.streamReader = new XMLEventStreamReader(eventReader);
}
@Test
void readAll() throws Exception {
while (streamReader.hasNext()) {
@@ -68,4 +73,30 @@ class XMLEventStreamReaderTests {
assertThat(XmlContent.from(writer)).isSimilarTo(XML, nodeFilter);
}
@ParameterizedTest // gh-36914
@CsvSource(textBlock = """
0, content
1, ontent
4, ent
6, t
7, ''
""")
void getTextCharactersHonorsSourceStart(int sourceStart, String expected) throws Exception {
advanceToCharacters();
// text node is "content" (7 chars); request an oversized buffer to ensure
// getTextCharacters(sourceStart, ...) does not read past the source
char[] target = new char[10];
int count = streamReader.getTextCharacters(sourceStart, target, 0, 10);
assertThat(count).isEqualTo(expected.length());
assertThat(new String(target, 0, count)).isEqualTo(expected);
}
private void advanceToCharacters() throws Exception {
while (streamReader.getEventType() != XMLStreamConstants.CHARACTERS) {
streamReader.next();
}
}
}