From 90d5f2dc62207dc6808ac0763e22acf9717fdec1 Mon Sep 17 00:00:00 2001 From: Martin Tzvetanov Grigorov Date: Wed, 7 Aug 2024 14:15:34 +0300 Subject: [PATCH] AVRO-4024: [Rust] Accept only "Nan", "INF", "-INF", "Infinity" and "-Infinity" This is what the Java SDK (via Jackson library) supports (https://github.com/apache/avro/pull/3066). This is what the C# SDK also would support (https://github.com/apache/avro/pull/3070) Signed-off-by: Martin Tzvetanov Grigorov --- lang/rust/avro/src/types.rs | 16 ++++++++-------- lang/rust/avro/tests/io.rs | 22 +++++++++++++++++++--- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/lang/rust/avro/src/types.rs b/lang/rust/avro/src/types.rs index e9d4a31bdea..b3ef2da7919 100644 --- a/lang/rust/avro/src/types.rs +++ b/lang/rust/avro/src/types.rs @@ -933,10 +933,10 @@ impl Value { /// IEEE 754 NaN and infinities are not valid JSON numbers. /// So they are represented in JSON as strings. fn parse_special_float(value: &str) -> Option { - match value.trim().to_ascii_lowercase().as_str() { - "nan" | "+nan" | "-nan" => Some(f32::NAN), - "inf" | "+inf" | "infinity" | "+infinity" => Some(f32::INFINITY), - "-inf" | "-infinity" => Some(f32::NEG_INFINITY), + match value { + "NaN" => Some(f32::NAN), + "INF" | "Infinity" => Some(f32::INFINITY), + "-INF" | "-Infinity" => Some(f32::NEG_INFINITY), _ => None, } } @@ -3142,10 +3142,10 @@ Field with name '"b"' is not a member of the map items"#, #[test] fn avro_4024_resolve_double_from_unknown_string_err() -> TestResult { let schema = Schema::parse_str(r#"{"type": "double"}"#)?; - let value = Value::String("blah".to_owned()); + let value = Value::String("unknown".to_owned()); match value.resolve(&schema) { Err(err @ Error::GetDouble(_)) => { - assert_eq!(format!("{err:?}"), r#"Double expected, got String("blah")"#); + assert_eq!(format!("{err:?}"), r#"Double expected, got String("unknown")"#); } other => { panic!("Expected Error::GetDouble, got {other:?}"); @@ -3157,10 +3157,10 @@ Field with name '"b"' is not a member of the map items"#, #[test] fn avro_4024_resolve_float_from_unknown_string_err() -> TestResult { let schema = Schema::parse_str(r#"{"type": "float"}"#)?; - let value = Value::String("blah".to_owned()); + let value = Value::String("unknown".to_owned()); match value.resolve(&schema) { Err(err @ Error::GetFloat(_)) => { - assert_eq!(format!("{err:?}"), r#"Float expected, got String("blah")"#); + assert_eq!(format!("{err:?}"), r#"Float expected, got String("unknown")"#); } other => { panic!("Expected Error::GetFloat, got {other:?}"); diff --git a/lang/rust/avro/tests/io.rs b/lang/rust/avro/tests/io.rs index 6a59a507132..40f1b212a81 100644 --- a/lang/rust/avro/tests/io.rs +++ b/lang/rust/avro/tests/io.rs @@ -107,14 +107,30 @@ fn default_value_examples() -> &'static Vec<(&'static str, &'static str, Value)> (r#""long""#, "5", Value::Long(5)), (r#""float""#, "1.1", Value::Float(1.1)), (r#""double""#, "1.1", Value::Double(1.1)), - (r#""float""#, r#"" +inf ""#, Value::Float(f32::INFINITY)), + (r#""float""#, r#""INF""#, Value::Float(f32::INFINITY)), + (r#""double""#, r#""INF""#, Value::Double(f64::INFINITY)), + ( + r#""float""#, + r#""Infinity""#, + Value::Float(f32::INFINITY), + ), + ( + r#""float""#, + r#""-Infinity""#, + Value::Float(f32::NEG_INFINITY), + ), + ( + r#""double""#, + r#""Infinity""#, + Value::Double(f64::INFINITY), + ), ( r#""double""#, r#""-Infinity""#, Value::Double(f64::NEG_INFINITY), ), - (r#""float""#, r#""-NAN""#, Value::Float(f32::NAN)), - (r#""double""#, r#""-NAN""#, Value::Double(f64::NAN)), + (r#""float""#, r#""NaN""#, Value::Float(f32::NAN)), + (r#""double""#, r#""NaN""#, Value::Double(f64::NAN)), ( r#"{"type": "fixed", "name": "F", "size": 2}"#, r#""a""#,