Skip to content

Commit f10de9e

Browse files
authored
Fix #311 by wrapping IonExceptions in IonParser (#313)
1 parent b082f58 commit f10de9e

File tree

2 files changed

+80
-6
lines changed

2 files changed

+80
-6
lines changed

ion/src/main/java/com/fasterxml/jackson/dataformat/ion/IonParser.java

+29-6
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,13 @@ public String getText() throws IOException
265265
case FIELD_NAME:
266266
return getCurrentName();
267267
case VALUE_STRING:
268-
return _reader.stringValue();
268+
try {
269+
// stringValue() will throw an UnknownSymbolException if we're
270+
// trying to get the text for a symbol id that cannot be resolved.
271+
return _reader.stringValue();
272+
} catch (UnknownSymbolException e) {
273+
throw _constructError(e.getMessage(), e);
274+
}
269275
case VALUE_NUMBER_INT:
270276
case VALUE_NUMBER_FLOAT:
271277
Number n = getNumberValue();
@@ -512,7 +518,12 @@ public JsonToken nextToken() throws IOException
512518
}
513519

514520
// any more tokens in this scope?
515-
IonType type = _reader.next();
521+
IonType type = null;
522+
try {
523+
type = _reader.next();
524+
} catch (IonException e) {
525+
_wrapError(e.getMessage(), e);
526+
}
516527
if (type == null) {
517528
if (_parsingContext.inRoot()) { // EOF?
518529
close();
@@ -528,7 +539,13 @@ public JsonToken nextToken() throws IOException
528539
boolean inStruct = !_parsingContext.inRoot() && _reader.isInStruct();
529540
// (isInStruct can return true for the first value read if the reader
530541
// was created from an IonValue that has a parent container)
531-
_parsingContext.setCurrentName(inStruct ? _reader.getFieldName() : null);
542+
try {
543+
// getFieldName() can throw an UnknownSymbolException if the text of the
544+
// field name symbol cannot be resolved.
545+
_parsingContext.setCurrentName(inStruct ? _reader.getFieldName() : null);
546+
} catch (UnknownSymbolException e) {
547+
_wrapError(e.getMessage(), e);
548+
}
532549
JsonToken t = _tokenFromType(type);
533550
// and return either field name first
534551
if (inStruct) {
@@ -542,9 +559,15 @@ public JsonToken nextToken() throws IOException
542559
/**
543560
* @see com.fasterxml.jackson.dataformat.ion.polymorphism.IonAnnotationTypeDeserializer
544561
*/
545-
public String[] getTypeAnnotations() {
546-
// Per its spec, will not return null
547-
return _reader.getTypeAnnotations();
562+
public String[] getTypeAnnotations() throws JsonParseException {
563+
try {
564+
// Per its spec, will not return null
565+
return _reader.getTypeAnnotations();
566+
} catch (UnknownSymbolException e) {
567+
// IonReader.getTypeAnnotations() can throw an UnknownSymbolException if the text of any
568+
// the annotation symbols cannot be resolved.
569+
throw _constructError(e.getMessage(), e);
570+
}
548571
}
549572

550573
@Override

ion/src/test/java/com/fasterxml/jackson/dataformat/ion/IonParserTest.java

+51
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package com.fasterxml.jackson.dataformat.ion;
1616

1717
import com.fasterxml.jackson.core.JsonParser;
18+
import com.fasterxml.jackson.core.JsonParseException;
1819
import com.fasterxml.jackson.core.JsonToken;
1920
import com.fasterxml.jackson.core.StreamReadCapability;
2021

@@ -125,4 +126,54 @@ public void testParserCapabilities() throws Exception {
125126
}
126127
}
127128

129+
130+
@Test(expected = JsonParseException.class)
131+
public void testIonExceptionIsWrapped() throws IOException {
132+
IonFactory f = new IonFactory();
133+
try (IonParser parser = (IonParser) f.createParser("[ 12, true ) ]")) {
134+
Assert.assertEquals(JsonToken.START_ARRAY, parser.nextToken());
135+
Assert.assertEquals(JsonToken.VALUE_NUMBER_INT, parser.nextValue());
136+
Assert.assertEquals(12, parser.getIntValue());
137+
Assert.assertEquals(JsonToken.VALUE_TRUE, parser.nextValue());
138+
parser.nextValue();
139+
}
140+
}
141+
142+
@Test(expected = JsonParseException.class)
143+
public void testUnknownSymbolExceptionForValueIsWrapped() throws IOException {
144+
IonFactory f = new IonFactory();
145+
try (IonParser parser = (IonParser) f.createParser("[ 12, $99 ]")) {
146+
Assert.assertEquals(JsonToken.START_ARRAY, parser.nextToken());
147+
Assert.assertEquals(JsonToken.VALUE_NUMBER_INT, parser.nextValue());
148+
Assert.assertEquals(12, parser.getIntValue());
149+
Assert.assertEquals(JsonToken.VALUE_STRING, parser.nextValue());
150+
parser.getValueAsString(); // Should encounter unknown symbol and fail
151+
}
152+
}
153+
154+
@Test(expected = JsonParseException.class)
155+
public void testUnknownSymbolExceptionForFieldNameIsWrapped() throws IOException {
156+
IonFactory f = new IonFactory();
157+
try (IonParser parser = (IonParser) f.createParser("{ a: 1, $99: 2 }")) {
158+
Assert.assertEquals(JsonToken.START_OBJECT, parser.nextToken());
159+
Assert.assertEquals(JsonToken.FIELD_NAME, parser.nextToken());
160+
Assert.assertEquals("a", parser.getCurrentName());
161+
Assert.assertEquals(JsonToken.VALUE_NUMBER_INT, parser.nextValue());
162+
Assert.assertEquals(1, parser.getIntValue());
163+
parser.nextValue(); // Should encounter unknown symbol and fail
164+
}
165+
}
166+
167+
@Test(expected = JsonParseException.class)
168+
public void testUnknownSymbolExceptionForAnnotationIsWrapped() throws IOException {
169+
IonFactory f = new IonFactory();
170+
try (IonParser parser = (IonParser) f.createParser("{ a: $99::1 }")) {
171+
Assert.assertEquals(JsonToken.START_OBJECT, parser.nextToken());
172+
Assert.assertEquals(JsonToken.FIELD_NAME, parser.nextToken());
173+
Assert.assertEquals("a", parser.getCurrentName());
174+
Assert.assertEquals(JsonToken.VALUE_NUMBER_INT, parser.nextValue());
175+
Assert.assertEquals(1, parser.getIntValue());
176+
parser.getTypeAnnotations(); // Should encounter unknown symbol and fail
177+
}
178+
}
128179
}

0 commit comments

Comments
 (0)