From a7dcf2a838624e6d5a3bf4d56eedfe33359efb7c Mon Sep 17 00:00:00 2001 From: m1212e <14091540+m1212e@users.noreply.github.com> Date: Wed, 8 Feb 2023 15:25:03 +0100 Subject: [PATCH] fix(napi): convert u64 to u32 in serialization (#1478) https://github.com/napi-rs/napi-rs/issues/1470 serde_json::Value parses positive integers to u64 types by default. When converting serde_json::Value to a js value, those numbers are converted to BigInts, even if they are within the bounds of the number primitive. The added checks converts an u64 to an u32 if possible to prevent this behavior. Co-authored-by: m1212e <-> --- crates/napi/src/js_values/ser.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/napi/src/js_values/ser.rs b/crates/napi/src/js_values/ser.rs index 237c17ab..75316d2f 100644 --- a/crates/napi/src/js_values/ser.rs +++ b/crates/napi/src/js_values/ser.rs @@ -95,10 +95,18 @@ impl<'env> Serializer for Ser<'env> { #[cfg(feature = "napi6")] fn serialize_u64(self, v: u64) -> Result { - self - .0 - .create_bigint_from_u64(v) - .map(|js_number| js_number.raw) + // https://github.com/napi-rs/napi-rs/issues/1470 + // serde_json::Value by default uses u64 for positive integers. This results in napirs using a BigInt instead of a number when converting to a js value. + // To avoid this, we need to check if the value fits into a smaller number type. + // If this is the case, we use the smaller type instead. + if v <= u32::MAX.into() { + self.serialize_u32(v as u32) + } else { + self + .0 + .create_bigint_from_u64(v) + .map(|js_number| js_number.raw) + } } #[cfg(all(