Skip to content

Commit

Permalink
JsonGenerator#close() is not idempotent and may cause data corruption.
Browse files Browse the repository at this point in the history
Signed-off-by: Jorge Bescos Gascon <jorge.bescos.gascon@oracle.com>
  • Loading branch information
jbescos authored and lukasj committed May 25, 2022
1 parent e44094f commit 06af407
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 11 deletions.
24 changes: 14 additions & 10 deletions impl/src/main/java/org/eclipse/parsson/JsonGeneratorImpl.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -90,6 +90,7 @@ private static enum Scope {
// flush the underlying output source
private final char buf[]; // capacity >= INT_MIN_VALUE_CHARS.length
private int len = 0;
private boolean closed = false;

JsonGeneratorImpl(Writer writer, BufferPool bufferPool) {
this.writer = writer;
Expand Down Expand Up @@ -515,16 +516,19 @@ private static class Context {

@Override
public void close() {
if (currentContext.scope != Scope.IN_NONE || currentContext.first) {
throw new JsonGenerationException(JsonMessages.GENERATOR_INCOMPLETE_JSON());
}
flushBuffer();
try {
writer.close();
} catch (IOException ioe) {
throw new JsonException(JsonMessages.GENERATOR_CLOSE_IO_ERR(), ioe);
if (!closed) {
if (currentContext.scope != Scope.IN_NONE || currentContext.first) {
throw new JsonGenerationException(JsonMessages.GENERATOR_INCOMPLETE_JSON());
}
flushBuffer();
try {
writer.close();
} catch (IOException ioe) {
throw new JsonException(JsonMessages.GENERATOR_CLOSE_IO_ERR(), ioe);
}
bufferPool.recycle(buf);
closed = true;
}
bufferPool.recycle(buf);
}

// begin, end-1 indexes represent characters that need not
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -22,6 +22,7 @@
import jakarta.json.*;
import jakarta.json.stream.*;
import java.io.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
Expand Down Expand Up @@ -542,4 +543,34 @@ public void testFlush() throws Exception {
assertEquals("{}", baos.toString("UTF-8"));
}

public void testClose() {
StringWriter sw = new StringWriter();
JsonGeneratorFactory factory = Json.createGeneratorFactory(Collections.emptyMap());
try (JsonGenerator generator = factory.createGenerator(sw)) {
generator.writeStartObject();
generator.writeEnd();
// Unnecessary close()
generator.close();
assertEquals("{}", sw.toString());
}
StringWriter sw1 = new StringWriter();
StringWriter sw2 = new StringWriter();
try (JsonGenerator generator1 = factory.createGenerator(sw1);
JsonGenerator generator2 = factory.createGenerator(sw2)) {
generator1.writeStartObject();
generator1.write("key", "value");

generator2.writeStartArray();
generator2.write("item");
generator2.write("item2");

generator1.write("key2", "value2");

generator2.writeEnd();

generator1.writeEnd();
}
assertEquals("{\"key\":\"value\",\"key2\":\"value2\"}", sw1.toString());
assertEquals("[\"item\",\"item2\"]", sw2.toString());
}
}

0 comments on commit 06af407

Please sign in to comment.