Skip to content

Commit 83c5694

Browse files
committed
Fix #763
1 parent 2dee63a commit 83c5694

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

release-notes/VERSION-2.x

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ JSON library.
3232
(contributed by @pjfanning)
3333
#759: JsonGenerator to provide current value to the context before starting objects
3434
(reported by Illia O)
35+
#763: `JsonFactory.createParser()` with `File` may leak `InputStream`s
3536

3637
2.13.3 (14-May-2022)
3738

src/main/java/com/fasterxml/jackson/core/JsonFactory.java

+14-3
Original file line numberDiff line numberDiff line change
@@ -1651,9 +1651,20 @@ public JsonGenerator createJsonGenerator(OutputStream out) throws IOException {
16511651
* @since 2.1
16521652
*/
16531653
protected JsonParser _createParser(InputStream in, IOContext ctxt) throws IOException {
1654-
// As per [JACKSON-259], may want to fully disable canonicalization:
1655-
return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
1656-
_objectCodec, _byteSymbolCanonicalizer, _rootCharSymbols, _factoryFeatures);
1654+
try {
1655+
return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
1656+
_objectCodec, _byteSymbolCanonicalizer, _rootCharSymbols, _factoryFeatures);
1657+
} catch (IOException | RuntimeException e) {
1658+
// 10-Jun-2022, tatu: For [core#763] may need to close InputStream here
1659+
if (ctxt.isResourceManaged()) {
1660+
try {
1661+
in.close();
1662+
} catch (Exception e2) {
1663+
e.addSuppressed(e2);
1664+
}
1665+
}
1666+
throw e;
1667+
}
16571668
}
16581669

16591670
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.fasterxml.jackson.core.json;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.net.URL;
7+
8+
import com.fasterxml.jackson.core.*;
9+
10+
// [core#763] (and [databind#3455]
11+
public class InputStreamInitTest
12+
extends com.fasterxml.jackson.core.BaseTest
13+
{
14+
static class FailingInputStream extends InputStream {
15+
public boolean closed = false;
16+
17+
@Override
18+
public void close() {
19+
closed = true;
20+
}
21+
22+
@Override
23+
public int read() throws IOException {
24+
throw new IOException("Will not read, ever!");
25+
}
26+
}
27+
28+
static class FailingJsonFactory extends JsonFactory {
29+
private static final long serialVersionUID = 1L;
30+
31+
public FailingInputStream lastStream;
32+
33+
@Override
34+
protected InputStream _fileInputStream(File f) throws IOException {
35+
return (lastStream = new FailingInputStream());
36+
}
37+
38+
@Override
39+
protected InputStream _optimizedStreamFromURL(URL url) throws IOException {
40+
return (lastStream = new FailingInputStream());
41+
}
42+
}
43+
44+
public void testForFile() throws Exception
45+
{
46+
final FailingJsonFactory jsonF = new FailingJsonFactory();
47+
try {
48+
/*JsonParser p =*/ jsonF.createParser(new File("/tmp/test.json"));
49+
fail("Should not pass");
50+
} catch (IOException e) {
51+
verifyException(e, "Will not read");
52+
}
53+
assertNotNull(jsonF.lastStream);
54+
assertTrue(jsonF.lastStream.closed);
55+
}
56+
57+
public void testForURL() throws Exception
58+
{
59+
final FailingJsonFactory jsonF = new FailingJsonFactory();
60+
try {
61+
/*JsonParser p =*/ jsonF.createParser(new URL("http://localhost:80/"));
62+
fail("Should not pass");
63+
} catch (IOException e) {
64+
verifyException(e, "Will not read");
65+
}
66+
assertNotNull(jsonF.lastStream);
67+
assertTrue(jsonF.lastStream.closed);
68+
}
69+
}

0 commit comments

Comments
 (0)