Skip to content

Commit e11373f

Browse files
committed
Unwrap XMLStreamException from cause
Closes: gh-24622
1 parent 623a019 commit e11373f

File tree

2 files changed

+39
-28
lines changed

2 files changed

+39
-28
lines changed

spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -197,6 +197,10 @@ public Object decode(DataBuffer dataBuffer, ResolvableType targetType,
197197
catch (XMLStreamException ex) {
198198
throw Exceptions.propagate(ex);
199199
}
200+
catch (Throwable ex) {
201+
ex = (ex.getCause() instanceof XMLStreamException ? ex.getCause() : ex);
202+
throw Exceptions.propagate(ex);
203+
}
200204
finally {
201205
DataBufferUtils.release(dataBuffer);
202206
}

spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlDecoderTests.java

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,11 +19,14 @@
1919
import java.nio.charset.StandardCharsets;
2020
import java.util.Collections;
2121
import java.util.List;
22+
import java.util.Map;
2223

2324
import javax.xml.namespace.QName;
25+
import javax.xml.stream.XMLStreamException;
2426
import javax.xml.stream.events.XMLEvent;
2527

2628
import org.junit.jupiter.api.Test;
29+
import reactor.core.Exceptions;
2730
import reactor.core.publisher.Flux;
2831
import reactor.core.publisher.Mono;
2932
import reactor.test.StepVerifier;
@@ -66,6 +69,8 @@ public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTests {
6669
"</pojo>" +
6770
"<root/>";
6871

72+
private static final Map<String, Object> HINTS = Collections.emptyMap();
73+
6974

7075
private final Jaxb2XmlDecoder decoder = new Jaxb2XmlDecoder();
7176

@@ -88,8 +93,7 @@ public void canDecode() {
8893

8994
@Test
9095
public void splitOneBranches() {
91-
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder
92-
.decode(stringBuffer(POJO_ROOT), null, null, Collections.emptyMap());
96+
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder.decode(toDataBufferMono(POJO_ROOT), null, null, HINTS);
9397
Flux<List<XMLEvent>> result = this.decoder.split(xmlEvents, new QName("pojo"));
9498

9599
StepVerifier.create(result)
@@ -109,9 +113,8 @@ public void splitOneBranches() {
109113
}
110114

111115
@Test
112-
public void splitMultipleBranches() throws Exception {
113-
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder
114-
.decode(stringBuffer(POJO_CHILD), null, null, Collections.emptyMap());
116+
public void splitMultipleBranches() {
117+
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder.decode(toDataBufferMono(POJO_CHILD), null, null, HINTS);
115118
Flux<List<XMLEvent>> result = this.decoder.split(xmlEvents, new QName("pojo"));
116119

117120

@@ -158,10 +161,9 @@ private static void assertCharacters(XMLEvent event, String expectedData) {
158161
}
159162

160163
@Test
161-
public void decodeSingleXmlRootElement() throws Exception {
162-
Mono<DataBuffer> source = stringBuffer(POJO_ROOT);
163-
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class),
164-
null, Collections.emptyMap());
164+
public void decodeSingleXmlRootElement() {
165+
Mono<DataBuffer> source = toDataBufferMono(POJO_ROOT);
166+
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class), null, HINTS);
165167

166168
StepVerifier.create(output)
167169
.expectNext(new Pojo("foofoo", "barbar"))
@@ -170,10 +172,9 @@ public void decodeSingleXmlRootElement() throws Exception {
170172
}
171173

172174
@Test
173-
public void decodeSingleXmlTypeElement() throws Exception {
174-
Mono<DataBuffer> source = stringBuffer(POJO_ROOT);
175-
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(TypePojo.class),
176-
null, Collections.emptyMap());
175+
public void decodeSingleXmlTypeElement() {
176+
Mono<DataBuffer> source = toDataBufferMono(POJO_ROOT);
177+
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(TypePojo.class), null, HINTS);
177178

178179
StepVerifier.create(output)
179180
.expectNext(new TypePojo("foofoo", "barbar"))
@@ -182,10 +183,9 @@ public void decodeSingleXmlTypeElement() throws Exception {
182183
}
183184

184185
@Test
185-
public void decodeMultipleXmlRootElement() throws Exception {
186-
Mono<DataBuffer> source = stringBuffer(POJO_CHILD);
187-
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(Pojo.class),
188-
null, Collections.emptyMap());
186+
public void decodeMultipleXmlRootElement() {
187+
Mono<DataBuffer> source = toDataBufferMono(POJO_CHILD);
188+
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(Pojo.class), null, HINTS);
189189

190190
StepVerifier.create(output)
191191
.expectNext(new Pojo("foo", "bar"))
@@ -195,10 +195,9 @@ public void decodeMultipleXmlRootElement() throws Exception {
195195
}
196196

197197
@Test
198-
public void decodeMultipleXmlTypeElement() throws Exception {
199-
Mono<DataBuffer> source = stringBuffer(POJO_CHILD);
200-
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(TypePojo.class),
201-
null, Collections.emptyMap());
198+
public void decodeMultipleXmlTypeElement() {
199+
Mono<DataBuffer> source = toDataBufferMono(POJO_CHILD);
200+
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(TypePojo.class), null, HINTS);
202201

203202
StepVerifier.create(output)
204203
.expectNext(new TypePojo("foo", "bar"))
@@ -208,19 +207,27 @@ public void decodeMultipleXmlTypeElement() throws Exception {
208207
}
209208

210209
@Test
211-
public void decodeError() throws Exception {
210+
public void decodeError() {
212211
Flux<DataBuffer> source = Flux.concat(
213-
stringBuffer("<pojo>"),
212+
toDataBufferMono("<pojo>"),
214213
Flux.error(new RuntimeException()));
215214

216-
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class),
217-
null, Collections.emptyMap());
215+
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class), null, HINTS);
218216

219217
StepVerifier.create(output)
220218
.expectError(RuntimeException.class)
221219
.verify();
222220
}
223221

222+
@Test // gh-24622
223+
public void decodeErrorWithXmlNotWellFormed() {
224+
Mono<DataBuffer> source = toDataBufferMono("<Response><tag>something</tag</Response>");
225+
Mono<Object> result = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class), null, HINTS);
226+
227+
StepVerifier.create(result).verifyErrorSatisfies(ex ->
228+
assertThat(Exceptions.unwrap(ex)).isInstanceOf(XMLStreamException.class));
229+
}
230+
224231
@Test
225232
public void toExpectedQName() {
226233
assertThat(this.decoder.toQName(Pojo.class)).isEqualTo(new QName("pojo"));
@@ -236,7 +243,7 @@ public void toExpectedQName() {
236243

237244
}
238245

239-
private Mono<DataBuffer> stringBuffer(String value) {
246+
private Mono<DataBuffer> toDataBufferMono(String value) {
240247
return Mono.defer(() -> {
241248
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
242249
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);

0 commit comments

Comments
 (0)