Fix #98
diff --git a/release-notes/VERSION b/release-notes/VERSION
index d99dc90..1fe975f 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -12,6 +12,7 @@
#93: Add `getFeatureMask()`, `setFeatureMask()` in `JsonGenerator`/`JsonParser`
#94: Allow coercion of String value "null" (similar to handling of null token)
#96: Add `JsonFactory.requiresPropertyOrdering()` introspection method
+#98: Improve handling of failures for `BigDecimal`, for "NaN" (and infinity)
- Improve `DefaultPrettyPrinter`, `Lf2SpacesIndenter` (from databind #276)
- Add `JsonGenerator.canOmitFields()` method to support discovery of
positional formats, needed for handling of filtering for CSV
diff --git a/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java b/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java
index 0bf4e77..ea40476 100644
--- a/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java
+++ b/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java
@@ -955,7 +955,7 @@
* to avoid rounding errors that non-decimal floating operations
* would incur
*/
- _numberBigDecimal = new BigDecimal(getText());
+ _numberBigDecimal = NumberInput.parseBigDecimal(getText());
} else if ((_numTypesValid & NR_BIGINT) != 0) {
_numberBigDecimal = new BigDecimal(_numberBigInt);
} else if ((_numTypesValid & NR_LONG) != 0) {
diff --git a/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java b/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java
index c8ba515..eb463b9 100644
--- a/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java
+++ b/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java
@@ -1,5 +1,7 @@
package com.fasterxml.jackson.core.io;
+import java.math.BigDecimal;
+
public final class NumberInput
{
/**
@@ -275,7 +277,7 @@
} catch (NumberFormatException e) { }
return defaultValue;
}
-
+
public static double parseDouble(String numStr) throws NumberFormatException
{
// [JACKSON-486]: avoid some nasty float representations... but should it be MIN_NORMAL or MIN_VALUE?
@@ -287,4 +289,31 @@
}
return Double.parseDouble(numStr);
}
+
+ public static BigDecimal parseBigDecimal(String numStr) throws NumberFormatException
+ {
+ try {
+ return new BigDecimal(numStr);
+ } catch (NumberFormatException e) {
+ throw _badBigDecimal(numStr);
+ }
+ }
+
+ public static BigDecimal parseBigDecimal(char[] buffer) throws NumberFormatException {
+ return parseBigDecimal(buffer, 0, buffer.length);
+ }
+
+ public static BigDecimal parseBigDecimal(char[] buffer, int offset, int len)
+ throws NumberFormatException
+ {
+ try {
+ return new BigDecimal(buffer, offset, len);
+ } catch (NumberFormatException e) {
+ throw _badBigDecimal(new String(buffer, offset, len));
+ }
+ }
+
+ private static NumberFormatException _badBigDecimal(String str) {
+ return new NumberFormatException("Value \""+str+"\" can not be represented as BigDecimal");
+ }
}
diff --git a/src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java b/src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java
index e0acf96..bab80e0 100644
--- a/src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java
+++ b/src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java
@@ -384,18 +384,18 @@
{
// Already got a pre-cut array?
if (_resultArray != null) {
- return new BigDecimal(_resultArray);
+ return NumberInput.parseBigDecimal(_resultArray);
}
// Or a shared buffer?
- if (_inputStart >= 0) {
- return new BigDecimal(_inputBuffer, _inputStart, _inputLen);
+ if ((_inputStart >= 0) && (_inputBuffer != null)) {
+ return NumberInput.parseBigDecimal(_inputBuffer, _inputStart, _inputLen);
}
// Or if not, just a single buffer (the usual case)
- if (_segmentSize == 0) {
- return new BigDecimal(_currentSegment, 0, _currentSize);
+ if ((_segmentSize == 0) && (_currentSegment != null)) {
+ return NumberInput.parseBigDecimal(_currentSegment, 0, _currentSize);
}
// If not, let's just get it aggregated...
- return new BigDecimal(contentsAsArray());
+ return NumberInput.parseBigDecimal(contentsAsArray());
}
/**
diff --git a/src/test/java/com/fasterxml/jackson/core/json/TestParserNonStandard.java b/src/test/java/com/fasterxml/jackson/core/json/TestParserNonStandard.java
index 21e0c45..c519bb8 100644
--- a/src/test/java/com/fasterxml/jackson/core/json/TestParserNonStandard.java
+++ b/src/test/java/com/fasterxml/jackson/core/json/TestParserNonStandard.java
@@ -380,9 +380,20 @@
assertToken(JsonToken.START_ARRAY, jp.nextToken());
assertToken(JsonToken.VALUE_NUMBER_FLOAT, jp.nextToken());
+
double d = jp.getDoubleValue();
assertTrue(Double.isNaN(d));
assertEquals("NaN", jp.getText());
+
+ // [Issue#98]
+ try {
+ /*BigDecimal dec =*/ jp.getDecimalValue();
+ fail("Should fail when trying to access NaN as BigDecimal");
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ verifyException(e, "can not be represented as BigDecimal");
+ }
+
assertToken(JsonToken.END_ARRAY, jp.nextToken());
jp.close();