This is an automated email from the ASF dual-hosted git repository.
clesaec pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/master by this push:
new ff0a4d513 AVRO-2885: better check int vs float value (#2401)
ff0a4d513 is described below
commit ff0a4d51336dcd1c8f0ec7485f8c28245634b641
Author: Christophe Le Saec <[email protected]>
AuthorDate: Thu Aug 17 13:57:42 2023 +0200
AVRO-2885: better check int vs float value (#2401)
---
.../main/java/org/apache/avro/io/JsonDecoder.java | 30 ++++++++++++++++------
.../java/org/apache/avro/io/TestJsonDecoder.java | 16 ++++++++++++
2 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/lang/java/avro/src/main/java/org/apache/avro/io/JsonDecoder.java
b/lang/java/avro/src/main/java/org/apache/avro/io/JsonDecoder.java
index c1c38511a..2ad496a5b 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/io/JsonDecoder.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/io/JsonDecoder.java
@@ -86,7 +86,7 @@ public class JsonDecoder extends ParsingDecoder implements
Parser.ActionHandler
* <p/>
* Otherwise, this JsonDecoder will reset its state and then reconfigure its
* input.
- *
+ *
* @param in The InputStream to read from. Cannot be null.
* @throws IOException
* @throws NullPointerException if {@code in} is {@code null}
@@ -109,7 +109,7 @@ public class JsonDecoder extends ParsingDecoder implements
Parser.ActionHandler
* <p/>
* Otherwise, this JsonDecoder will reset its state and then reconfigure its
* input.
- *
+ *
* @param in The String to read from. Cannot be null.
* @throws IOException
* @throws NullPointerException if {@code in} is {@code null}
@@ -157,25 +157,39 @@ public class JsonDecoder extends ParsingDecoder
implements Parser.ActionHandler
@Override
public int readInt() throws IOException {
advance(Symbol.INT);
- if (in.getCurrentToken().isNumeric()) {
+ if (in.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) {
int result = in.getIntValue();
in.nextToken();
return result;
- } else {
- throw error("int");
}
+ if (in.getCurrentToken() == JsonToken.VALUE_NUMBER_FLOAT) {
+ float value = in.getFloatValue();
+ if (Math.abs(value - Math.round(value)) <= Float.MIN_VALUE) {
+ int result = Math.round(value);
+ in.nextToken();
+ return result;
+ }
+ }
+ throw error("int");
}
@Override
public long readLong() throws IOException {
advance(Symbol.LONG);
- if (in.getCurrentToken().isNumeric()) {
+ if (in.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) {
long result = in.getLongValue();
in.nextToken();
return result;
- } else {
- throw error("long");
}
+ if (in.getCurrentToken() == JsonToken.VALUE_NUMBER_FLOAT) {
+ double value = in.getDoubleValue();
+ if (Math.abs(value - Math.round(value)) <= Double.MIN_VALUE) {
+ long result = Math.round(value);
+ in.nextToken();
+ return result;
+ }
+ }
+ throw error("long");
}
@Override
diff --git
a/lang/java/avro/src/test/java/org/apache/avro/io/TestJsonDecoder.java
b/lang/java/avro/src/test/java/org/apache/avro/io/TestJsonDecoder.java
index 693fbd421..050571396 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/io/TestJsonDecoder.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/io/TestJsonDecoder.java
@@ -19,11 +19,17 @@ package org.apache.avro.io;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.apache.avro.AvroTypeException;
import org.apache.avro.Schema;
+import org.apache.avro.SchemaBuilder;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericRecord;
+
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.io.IOException;
+
public class TestJsonDecoder {
@Test
@@ -76,4 +82,14 @@ public class TestJsonDecoder {
assertEquals(200, in.readLong());
in.skipArray();
}
+
+ @Test
+ void testIntWithError() throws IOException {
+ Schema schema =
SchemaBuilder.builder("test").record("example").fields().requiredInt("id").endRecord();
+ String record = "{ \"id\": -1.2 }";
+
+ GenericDatumReader<GenericRecord> reader = new
GenericDatumReader<>(schema, schema);
+ JsonDecoder decoder = DecoderFactory.get().jsonDecoder(schema, record);
+ Assertions.assertThrows(AvroTypeException.class, () -> reader.read(null,
decoder));
+ }
}