From c6fefc1b8348cb7c2c2cbfe071c9d32d8d2d91de Mon Sep 17 00:00:00 2001 From: Patrick Freed Date: Mon, 2 Aug 2021 14:43:37 -0400 Subject: [PATCH 1/2] minor: fix clippy --- src/bson.rs | 2 +- src/de/serde.rs | 2 +- src/extjson/de.rs | 2 +- src/ser/mod.rs | 8 ++++---- src/tests/serde.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/bson.rs b/src/bson.rs index 1c28a050..febe00ad 100644 --- a/src/bson.rs +++ b/src/bson.rs @@ -122,7 +122,7 @@ impl Display for Bson { }) => write!(fmt, "/{}/{}", pattern, options), Bson::JavaScriptCode(ref code) | Bson::JavaScriptCodeWithScope(JavaScriptCodeWithScope { ref code, .. }) => { - fmt.write_str(&code) + fmt.write_str(code) } Bson::Int32(i) => write!(fmt, "{}", i), Bson::Int64(i) => write!(fmt, "{}", i), diff --git a/src/de/serde.rs b/src/de/serde.rs index 31efe2af..11dd181e 100644 --- a/src/de/serde.rs +++ b/src/de/serde.rs @@ -325,7 +325,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { Bson::Binary(Binary { subtype: BinarySubtype::Generic, ref bytes, - }) => visitor.visit_bytes(&bytes), + }) => visitor.visit_bytes(bytes), binary @ Bson::Binary(..) => visitor.visit_map(MapDeserializer { iter: binary.to_extended_document().into_iter(), value: None, diff --git a/src/extjson/de.rs b/src/extjson/de.rs index 9d778367..e4b6495a 100644 --- a/src/extjson/de.rs +++ b/src/extjson/de.rs @@ -200,7 +200,7 @@ impl TryFrom for Bson { .or_else(|| x.as_f64().map(Bson::from)) .ok_or_else(|| { Error::invalid_value( - Unexpected::Other(&format!("{}", x).as_str()), + Unexpected::Other(format!("{}", x).as_str()), &"a number that could fit in i32, i64, or f64", ) }), diff --git a/src/ser/mod.rs b/src/ser/mod.rs index 3fb14ad7..964a30e0 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -110,8 +110,8 @@ pub(crate) fn serialize_bson( match *val { Bson::Double(v) => write_f64(writer, v), - Bson::String(ref v) => write_string(writer, &v), - Bson::Array(ref v) => serialize_array(writer, &v), + Bson::String(ref v) => write_string(writer, v), + Bson::Array(ref v) => serialize_array(writer, v), Bson::Document(ref v) => v.to_writer(writer), Bson::Boolean(v) => writer .write_all(&[if v { 0x01 } else { 0x00 }]) @@ -123,7 +123,7 @@ pub(crate) fn serialize_bson( write_cstring(writer, pattern)?; write_cstring(writer, options) } - Bson::JavaScriptCode(ref code) => write_string(writer, &code), + Bson::JavaScriptCode(ref code) => write_string(writer, code), Bson::ObjectId(ref id) => writer.write_all(&id.bytes()).map_err(From::from), Bson::JavaScriptCodeWithScope(JavaScriptCodeWithScope { ref code, @@ -160,7 +160,7 @@ pub(crate) fn serialize_bson( (v.timestamp() * 1000) + (v.nanosecond() / 1_000_000) as i64, ), Bson::Null => Ok(()), - Bson::Symbol(ref v) => write_string(writer, &v), + Bson::Symbol(ref v) => write_string(writer, v), #[cfg(not(feature = "decimal128"))] Bson::Decimal128(ref v) => { writer.write_all(&v.bytes)?; diff --git a/src/tests/serde.rs b/src/tests/serde.rs index 10e5e7ee..7b0933f9 100644 --- a/src/tests/serde.rs +++ b/src/tests/serde.rs @@ -697,7 +697,7 @@ fn test_datetime_helpers() { } } }"#; - let json: Value = serde_json::from_str(&date).unwrap(); + let json: Value = serde_json::from_str(date).unwrap(); let b: B = serde_json::from_value(json).unwrap(); let expected: chrono::DateTime = chrono::DateTime::from_str("2020-06-09 10:58:07.095 UTC").unwrap(); From 76780345ab1d4eec50f9cea05f3dbf2c34c4e644 Mon Sep 17 00:00:00 2001 From: Patrick Freed Date: Mon, 2 Aug 2021 14:40:08 -0400 Subject: [PATCH 2/2] fix crashes when decimal128 in document when deserializing --- serde-tests/Cargo.toml | 1 + serde-tests/test.rs | 22 +++++++++++++++++++++- src/bson.rs | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/serde-tests/Cargo.toml b/serde-tests/Cargo.toml index 8244be08..96feb0f1 100644 --- a/serde-tests/Cargo.toml +++ b/serde-tests/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] bson = { path = ".." } serde = { version = "1.0", features = ["derive"] } +hex = "0.4" [lib] name = "serde_tests" diff --git a/serde-tests/test.rs b/serde-tests/test.rs index 938ffebc..bccbbfb1 100644 --- a/serde-tests/test.rs +++ b/serde-tests/test.rs @@ -4,7 +4,7 @@ use serde::{self, de::Unexpected, Deserialize, Serialize}; use std::collections::{BTreeMap, HashSet}; -use bson::{Bson, Deserializer, Serializer}; +use bson::{Bson, Deserializer, Document, Serializer}; macro_rules! bson { ([]) => {{ bson::Bson::Array(Vec::new()) }}; @@ -635,3 +635,23 @@ fn empty_arrays2() { }); assert_eq!(v, t!(Deserialize::deserialize(d))); } + +#[test] +fn decimal128() { + #[derive(Serialize, Deserialize)] + struct Wrapper { + d: Bson, + } + + // { "d": Decimal128("2") } from "Regular - 2" corpus test + let bytes = hex::decode("180000001364000200000000000000000000000000403000").unwrap(); + let doc = Document::from_reader(&mut bytes.as_slice()).unwrap(); + + assert!(matches!(doc.get("d"), Some(Bson::Decimal128(_)))); + + let deserialized: Wrapper = bson::from_document(doc.clone()).unwrap(); + assert!(matches!(deserialized.d, Bson::Decimal128(_))); + + let round = bson::to_document(&deserialized).unwrap(); + assert_eq!(round, doc); +} diff --git a/src/bson.rs b/src/bson.rs index febe00ad..eeaaf996 100644 --- a/src/bson.rs +++ b/src/bson.rs @@ -574,6 +574,15 @@ impl Bson { "$numberDecimal": (v.to_string()) } } + #[cfg(not(feature = "decimal128"))] + Bson::Decimal128(ref v) => { + doc! { + "$numberDecimalBytes": Bson::Binary(Binary { + bytes: v.bytes.to_vec(), + subtype: BinarySubtype::Generic, + }).to_extended_document() + } + } Bson::Undefined => { doc! { "$undefined": true, @@ -666,6 +675,16 @@ impl Bson { } } + #[cfg(not(feature = "decimal128"))] + ["$numberDecimalBytes"] => { + if let Ok(d) = doc.get_binary_generic("$numberDecimalBytes") { + let boxed_slice = d.clone().into_boxed_slice(); + if let Ok(ba) = Box::<[u8; 128 / 8]>::try_from(boxed_slice) { + return Bson::Decimal128(Decimal128 { bytes: *ba }); + } + } + } + ["$binary"] => { if let Some(binary) = Binary::from_extended_doc(&doc) { return Bson::Binary(binary);