Skip to content

Commit 796ce3d

Browse files
committed
Throw an exception if the same name is written to JSON more than once
Update `JsonValueWriter` to track written names and throw an exception if there is a duplicate. Closes gh-43041
1 parent f38e1a5 commit 796ce3d

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/JsonValueWriter.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import java.util.ArrayDeque;
2222
import java.util.Arrays;
2323
import java.util.Deque;
24+
import java.util.HashSet;
2425
import java.util.Map;
26+
import java.util.Set;
2527
import java.util.function.BiConsumer;
2628
import java.util.function.Consumer;
2729
import java.util.function.Predicate;
@@ -223,6 +225,8 @@ private <N, V> void writePair(N name, V value) {
223225
ActiveSeries activeSeries = this.activeSeries.peek();
224226
Assert.notNull(activeSeries, "No series has been started");
225227
activeSeries.incrementIndexAndAddCommaIfRequired();
228+
Assert.state(activeSeries.addName(processedName),
229+
() -> "The name '" + processedName + "' has already been written");
226230
writeString(processedName);
227231
append(":");
228232
write(value);
@@ -359,10 +363,16 @@ private final class ActiveSeries {
359363

360364
private int index;
361365

366+
private Set<String> names = new HashSet<>();
367+
362368
private ActiveSeries(Series series) {
363369
this.series = series;
364370
}
365371

372+
boolean addName(String processedName) {
373+
return this.names.add(processedName);
374+
}
375+
366376
MemberPath updatePath(MemberPath path) {
367377
return (this.series != Series.ARRAY) ? path : path.child(this.index);
368378
}

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/json/JsonValueWriterTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import static org.assertj.core.api.Assertions.assertThat;
3131
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
32+
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
3233

3334
/**
3435
* Tests for {@link JsonValueWriter} .
@@ -193,6 +194,16 @@ void writePairs() {
193194
{"a":"A","b":"B"}""");
194195
}
195196

197+
@Test
198+
void writePairsWhenDuplicateThrowsException() {
199+
assertThatIllegalStateException().isThrownBy(() -> doWrite((valueWriter) -> {
200+
valueWriter.start(Series.OBJECT);
201+
valueWriter.writePairs(Map.of("a", "A")::forEach);
202+
valueWriter.writePairs(Map.of("a", "B")::forEach);
203+
valueWriter.end(Series.OBJECT);
204+
})).withMessage("The name 'a' has already been written");
205+
}
206+
196207
@Test
197208
void writeArray() {
198209
List<String> list = List.of("a", "b", "c");

0 commit comments

Comments
 (0)