From 24dc1841cce2d4e902bdd211f971f3bbce12eeee Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Fri, 30 Oct 2020 09:38:24 +0200 Subject: [PATCH 1/2] Add a check for strings disguised as leading zeros followed by numbers Resolves Issue #179 According to the YAML 1.2 spec (https://yaml.org/spec/1.2/spec.html#id2761292) numbers sequences with a leading zeros (that are not special encoding identifiers such as 0x, 0b, etc) are actually strings. This patch handles this case, all existing tests still pass. --- src/de.rs | 7 +++++++ tests/test_value.rs | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/de.rs b/src/de.rs index aa58587f..1932e271 100644 --- a/src/de.rs +++ b/src/de.rs @@ -556,6 +556,13 @@ where return visitor.visit_i64(n); } } + // After handling the different number encodings above + // if we are left with leading zero(s) followed by numeric characters + // this is in fact a string according to the YAML 1.2 spec + // https://yaml.org/spec/1.2/spec.html#id2761292 + if v.len() > 1 && v.starts_with("0") && v.chars().all(char::is_numeric) { + return visitor.visit_str(v); + } if let Ok(n) = v.parse() { return visitor.visit_u64(n); } diff --git a/tests/test_value.rs b/tests/test_value.rs index 3a4ec2ab..079186b5 100644 --- a/tests/test_value.rs +++ b/tests/test_value.rs @@ -10,6 +10,9 @@ fn test_nan() { let neg_fake_nan = serde_yaml::from_str::("-.nan").unwrap(); assert!(neg_fake_nan.is_string()); + let num_string = serde_yaml::from_str::("01").unwrap(); + assert!(num_string.is_string()); + let significand_mask = 0xF_FFFF_FFFF_FFFF; let bits = (f64::NAN.to_bits() ^ significand_mask) | 1; let different_pos_nan = Value::Number(Number::from(f64::from_bits(bits))); From 7b44a8ece1b030a3b4d5237dd9d8189603b77783 Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Fri, 30 Oct 2020 10:01:15 +0200 Subject: [PATCH 2/2] Fix the clippy formatting warning --- src/de.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de.rs b/src/de.rs index 1932e271..912347c8 100644 --- a/src/de.rs +++ b/src/de.rs @@ -560,7 +560,7 @@ where // if we are left with leading zero(s) followed by numeric characters // this is in fact a string according to the YAML 1.2 spec // https://yaml.org/spec/1.2/spec.html#id2761292 - if v.len() > 1 && v.starts_with("0") && v.chars().all(char::is_numeric) { + if v.len() > 1 && v.starts_with('0') && v.chars().all(char::is_numeric) { return visitor.visit_str(v); } if let Ok(n) = v.parse() {