From bca6e289e0263b0ea7487261850a3f7cfee6e171 Mon Sep 17 00:00:00 2001 From: Doug Roper Date: Sun, 19 Dec 2021 22:10:46 -0500 Subject: [PATCH] Set StreamReadCapability.EXACT_FLOATS=true --- .../jackson/dataformat/cbor/CBORParser.java | 3 +- .../dataformat/cbor/FloatPrecisionTest.java | 41 +++++++++++++++++ .../dataformat/smile/SmileParserBase.java | 6 ++- .../dataformat/smile/FloatPrecisionTest.java | 45 +++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/FloatPrecisionTest.java create mode 100644 smile/src/test/java/com/fasterxml/jackson/dataformat/smile/FloatPrecisionTest.java diff --git a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java index 756b7bea7..50abd402a 100644 --- a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java +++ b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java @@ -420,8 +420,7 @@ public int getFormatFeatures() { @Override // since 2.12 public JacksonFeatureSet getReadCapabilities() { - // Defaults are fine - return DEFAULT_READ_CAPABILITIES; + return DEFAULT_READ_CAPABILITIES.with(StreamReadCapability.EXACT_FLOATS); } /* diff --git a/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/FloatPrecisionTest.java b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/FloatPrecisionTest.java new file mode 100644 index 000000000..9b301b7e2 --- /dev/null +++ b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/FloatPrecisionTest.java @@ -0,0 +1,41 @@ +package com.fasterxml.jackson.dataformat.cbor; + +import java.io.ByteArrayOutputStream; +import java.math.BigDecimal; + +import static org.junit.Assert.assertArrayEquals; + + +// for [jackson-core#730] +public class FloatPrecisionTest extends CBORTestBase +{ + // for [jackson-core#730] + public void testFloatRoundtrips() throws Exception + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + CBORGenerator gen = cborGenerator(out); + gen.writeStartArray(); + + gen.writeNumber(Float.MIN_VALUE); + gen.writeNumber(0.0f); + gen.writeNumber(Float.MAX_VALUE); + + gen.writeNumber(Double.MIN_VALUE); + gen.writeNumber(0.0d); + gen.writeNumber(Double.MAX_VALUE); + + gen.writeNumber(new BigDecimal("1e999")); + gen.writeEndArray(); + gen.close(); + byte[] expected = out.toByteArray(); + + CBORParser parser = cborParser(expected); + ByteArrayOutputStream out2 = new ByteArrayOutputStream(); + CBORGenerator gen2 = cborGenerator(out2); + parser.nextToken(); + gen2.copyCurrentStructure(parser); + gen2.close(); + byte[] actual = out2.toByteArray(); + assertArrayEquals(expected, actual); + } +} diff --git a/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParserBase.java b/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParserBase.java index 872ec7886..d0e131ff6 100644 --- a/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParserBase.java +++ b/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParserBase.java @@ -319,10 +319,12 @@ public final JsonParser overrideFormatFeatures(int values, int mask) { return this; } + protected final static JacksonFeatureSet SMILE_READ_CAPABILITIES + = DEFAULT_READ_CAPABILITIES.with(StreamReadCapability.EXACT_FLOATS); + @Override // since 2.12 public JacksonFeatureSet getReadCapabilities() { - // Defaults are fine - return DEFAULT_READ_CAPABILITIES; + return SMILE_READ_CAPABILITIES; } /* diff --git a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/FloatPrecisionTest.java b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/FloatPrecisionTest.java new file mode 100644 index 000000000..34fa4ccd3 --- /dev/null +++ b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/FloatPrecisionTest.java @@ -0,0 +1,45 @@ +package com.fasterxml.jackson.dataformat.smile; + +import com.fasterxml.jackson.dataformat.smile.BaseTestForSmile; +import com.fasterxml.jackson.dataformat.smile.SmileGenerator; +import com.fasterxml.jackson.dataformat.smile.SmileParser; + +import java.io.ByteArrayOutputStream; +import java.math.BigDecimal; + +import static org.junit.Assert.assertArrayEquals; + + +// for [jackson-core#730] +public class FloatPrecisionTest extends BaseTestForSmile +{ + // for [jackson-core#730] + public void testFloatRoundtrips() throws Exception + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + SmileGenerator gen = smileGenerator(out, true); + gen.writeStartArray(); + + gen.writeNumber(Float.MIN_VALUE); + gen.writeNumber(0.0f); + gen.writeNumber(Float.MAX_VALUE); + + gen.writeNumber(Double.MIN_VALUE); + gen.writeNumber(0.0d); + gen.writeNumber(Double.MAX_VALUE); + + gen.writeNumber(new BigDecimal("1e999")); + gen.writeEndArray(); + gen.close(); + byte[] expected = out.toByteArray(); + + SmileParser parser = _smileParser(expected); + ByteArrayOutputStream out2 = new ByteArrayOutputStream(); + SmileGenerator gen2 = smileGenerator(out2, true); + parser.nextToken(); + gen2.copyCurrentStructure(parser); + gen2.close(); + byte[] actual = out2.toByteArray(); + assertArrayEquals(expected, actual); + } +}