Skip to content

Commit

Permalink
Add parser feature flag to turn on/off tagged array BigDecimal expone…
Browse files Browse the repository at this point in the history
…nt negation, so bug FasterXML#139 fix can be toggled on/off to support backwards compatibility.
  • Loading branch information
msqr committed Dec 17, 2019
1 parent c02d615 commit 2ceafa5
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@ public class CBORParser extends ParserMinimalBase
*/
public enum Feature implements FormatFeature
{
// BOGUS(false)
;
/**
* Feature that can be eanbled to negate a typed array BigDecimal.
*<p>
* Default provides compatibility with {@code CBORGenerator} from < v2.10.
*
* @since 2.10.1.SNF
*/
CBOR_BIG_DECIMAL_EXPONENT_NEGATE(false),
;

final boolean _defaultState;
final int _mask;
Expand Down Expand Up @@ -73,6 +80,12 @@ private Feature(boolean defaultState) {
* Codec used for data binding when (if) requested.
*/
protected ObjectCodec _objectCodec;

/**
* Toggle backwards-compatibility with < v2.10 typed array
* BigDecimal handling.
*/
final private boolean _bigDecimalNegate;

/*
/**********************************************************
Expand Down Expand Up @@ -366,6 +379,8 @@ public CBORParser(IOContext ctxt, int parserFeatures, int cborFeatures,

_tokenInputRow = -1;
_tokenInputCol = -1;

_bigDecimalNegate = Feature.CBOR_BIG_DECIMAL_EXPONENT_NEGATE.enabledIn(cborFeatures);
}

@Override
Expand Down Expand Up @@ -884,7 +899,7 @@ protected JsonToken _handleTaggedArray(int tag, int len) throws IOException
// 27-Nov-2019, tatu: As per [dataformats-binary#139] need to change sign here
// if decoding CBOR generated < v2.10
int exp = getIntValue();
if ( exp < 0 ) {
if ( _bigDecimalNegate ) {
exp = -exp;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.math.BigInteger;

import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
import com.fasterxml.jackson.dataformat.cbor.CBORGenerator;
import com.fasterxml.jackson.dataformat.cbor.CBORParser;
import com.fasterxml.jackson.dataformat.cbor.CBORTestBase;
Expand All @@ -20,10 +21,8 @@ public void testBigDecimalShort() throws Exception
_testBigDecimal(BigDecimal.ONE.scaleByPowerOfTen(-1));
_testBigDecimal(BigDecimal.ONE.scaleByPowerOfTen(-3));
_testBigDecimal(BigDecimal.ONE.scaleByPowerOfTen(-100));
/* Disabled for SNF patch
_testBigDecimal(BigDecimal.ONE.scaleByPowerOfTen(3));
_testBigDecimal(BigDecimal.ONE.scaleByPowerOfTen(137));
*/

_testBigDecimal(new BigDecimal("0.01"));
_testBigDecimal(new BigDecimal("0.33"));
Expand Down Expand Up @@ -56,7 +55,9 @@ private void _testBigDecimal(BigDecimal expValue) throws Exception
byte[] b = sourceBytes.toByteArray();

// but verify that the original content can be parsed
CBORParser parser = cborParser(b);
final CBORFactory f = new CBORFactory();
f.enable(CBORParser.Feature.CBOR_BIG_DECIMAL_EXPONENT_NEGATE);
CBORParser parser = cborParser(f, b);
assertToken(JsonToken.START_OBJECT, parser.nextToken());
assertToken(JsonToken.FIELD_NAME, parser.nextToken());
assertEquals("a", parser.getCurrentName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,9 @@ public void testBigDecimalType() throws IOException {
generator.close();

final byte[] b = out.toByteArray();
try (CBORParser parser = cborParser(b)) {
CBORFactory f = new CBORFactory();
f.enable(CBORParser.Feature.CBOR_BIG_DECIMAL_EXPONENT_NEGATE);
try (CBORParser parser = cborParser(f, b)) {
assertEquals(JsonToken.VALUE_NUMBER_FLOAT, parser.nextToken());
assertEquals(NumberType.BIG_DECIMAL, parser.getNumberType());
assertEquals(NR, parser.getDecimalValue());
Expand All @@ -354,7 +356,9 @@ public void testBigDecimalType2() throws IOException {
0x21, // int -- -2
0x19, 0x6a, (byte) 0xb3 // int 27315
};
try (CBORParser parser = cborParser(spec)) {
CBORFactory f = new CBORFactory();
f.enable(CBORParser.Feature.CBOR_BIG_DECIMAL_EXPONENT_NEGATE);
try (CBORParser parser = cborParser(f, spec)) {
assertEquals(JsonToken.VALUE_NUMBER_FLOAT, parser.nextToken());
assertEquals(NumberType.BIG_DECIMAL, parser.getNumberType());
assertEquals(new BigDecimal("273.15"), parser.getDecimalValue());
Expand Down

0 comments on commit 2ceafa5

Please sign in to comment.