Skip to content

Commit 7e8c859

Browse files
authored
RUST-2057 Test relaxed encoding of y10k dates (#572)
1 parent 174fe65 commit 7e8c859

File tree

4 files changed

+71
-9
lines changed

4 files changed

+71
-9
lines changed

src/decimal128.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,9 @@ impl std::str::FromStr for ParsedDecimal128 {
356356
exp_str = post;
357357
}
358358
}
359-
let mut exp = exp_str.parse::<i16>().map_err(|e| {
359+
// Initially parse the exponent as an i128 to handle corner cases with zero
360+
// coefficients and very large exponents.
361+
let mut wide_exp = exp_str.parse::<i128>().map_err(|e| {
360362
Error::decimal128(Decimal128ErrorKind::InvalidExponent {}).with_message(e)
361363
})?;
362364

@@ -367,7 +369,7 @@ impl std::str::FromStr for ParsedDecimal128 {
367369
.len()
368370
.try_into()
369371
.map_err(|_| Error::decimal128(Decimal128ErrorKind::Underflow {}))?;
370-
exp = exp
372+
wide_exp = wide_exp
371373
.checked_sub(exp_adj)
372374
.ok_or_else(|| Error::decimal128(Decimal128ErrorKind::Underflow {}))?;
373375
joined_str = format!("{}{}", pre, post);
@@ -386,16 +388,17 @@ impl std::str::FromStr for ParsedDecimal128 {
386388
let exp_adj = (len - decimal_str.len())
387389
.try_into()
388390
.map_err(|_| Error::decimal128(Decimal128ErrorKind::Overflow {}))?;
389-
exp = exp
391+
wide_exp = wide_exp
390392
.checked_add(exp_adj)
391393
.ok_or_else(|| Error::decimal128(Decimal128ErrorKind::Overflow {}))?;
392394
}
393395
}
394396

395397
// Check exponent limits
396-
if exp < Exponent::TINY {
398+
const TINY: i128 = Exponent::TINY as i128;
399+
if wide_exp < TINY {
397400
if decimal_str != "0" {
398-
let delta = (Exponent::TINY - exp)
401+
let delta = (TINY - wide_exp)
399402
.try_into()
400403
.map_err(|_| Error::decimal128(Decimal128ErrorKind::Overflow {}))?;
401404
let new_precision = decimal_str
@@ -404,12 +407,13 @@ impl std::str::FromStr for ParsedDecimal128 {
404407
.ok_or_else(|| Error::decimal128(Decimal128ErrorKind::Overflow {}))?;
405408
decimal_str = round_decimal_str(decimal_str, new_precision)?;
406409
}
407-
exp = Exponent::TINY;
410+
wide_exp = Exponent::TINY.into();
408411
}
409412
let padded_str;
410-
if exp > Exponent::MAX {
413+
const MAX: i128 = Exponent::MAX as i128;
414+
if wide_exp > MAX {
411415
if decimal_str != "0" {
412-
let delta = (exp - Exponent::MAX)
416+
let delta = (wide_exp - MAX)
413417
.try_into()
414418
.map_err(|_| Error::decimal128(Decimal128ErrorKind::Overflow {}))?;
415419
if decimal_str
@@ -423,10 +427,13 @@ impl std::str::FromStr for ParsedDecimal128 {
423427
padded_str = format!("{}{}", decimal_str, "0".repeat(delta));
424428
decimal_str = &padded_str;
425429
}
426-
exp = Exponent::MAX;
430+
wide_exp = Exponent::MAX.into();
427431
}
428432

429433
// Assemble the final value
434+
let exp: i16 = wide_exp
435+
.try_into()
436+
.map_err(|_| Error::decimal128(Decimal128ErrorKind::Overflow {}))?;
430437
let exponent = Exponent::from_native(exp);
431438
let coeff: u128 = decimal_str.parse().map_err(|e: ParseIntError| {
432439
Error::decimal128(Decimal128ErrorKind::InvalidCoefficient {}).with_message(e)

src/tests/spec/json/bson-corpus/binary.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,36 @@
7474
"description": "$type query operator (conflicts with legacy $binary form with $type field)",
7575
"canonical_bson": "180000000378001000000010247479706500020000000000",
7676
"canonical_extjson": "{\"x\" : { \"$type\" : {\"$numberInt\": \"2\"}}}"
77+
},
78+
{
79+
"description": "subtype 0x09 Vector FLOAT32",
80+
"canonical_bson": "170000000578000A0000000927000000FE420000E04000",
81+
"canonical_extjson": "{\"x\": {\"$binary\": {\"base64\": \"JwAAAP5CAADgQA==\", \"subType\": \"09\"}}}"
82+
},
83+
{
84+
"description": "subtype 0x09 Vector INT8",
85+
"canonical_bson": "11000000057800040000000903007F0700",
86+
"canonical_extjson": "{\"x\": {\"$binary\": {\"base64\": \"AwB/Bw==\", \"subType\": \"09\"}}}"
87+
},
88+
{
89+
"description": "subtype 0x09 Vector PACKED_BIT",
90+
"canonical_bson": "11000000057800040000000910007F0700",
91+
"canonical_extjson": "{\"x\": {\"$binary\": {\"base64\": \"EAB/Bw==\", \"subType\": \"09\"}}}"
92+
},
93+
{
94+
"description": "subtype 0x09 Vector (Zero-length) FLOAT32",
95+
"canonical_bson": "0F0000000578000200000009270000",
96+
"canonical_extjson": "{\"x\": {\"$binary\": {\"base64\": \"JwA=\", \"subType\": \"09\"}}}"
97+
},
98+
{
99+
"description": "subtype 0x09 Vector (Zero-length) INT8",
100+
"canonical_bson": "0F0000000578000200000009030000",
101+
"canonical_extjson": "{\"x\": {\"$binary\": {\"base64\": \"AwA=\", \"subType\": \"09\"}}}"
102+
},
103+
{
104+
"description": "subtype 0x09 Vector (Zero-length) PACKED_BIT",
105+
"canonical_bson": "0F0000000578000200000009100000",
106+
"canonical_extjson": "{\"x\": {\"$binary\": {\"base64\": \"EAA=\", \"subType\": \"09\"}}}"
77107
}
78108
],
79109
"decodeErrors": [

src/tests/spec/json/bson-corpus/datetime.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
{
2525
"description" : "Y10K",
2626
"canonical_bson" : "1000000009610000DC1FD277E6000000",
27+
"relaxed_extjson" : "{\"a\":{\"$date\":{\"$numberLong\":\"253402300800000\"}}}",
2728
"canonical_extjson" : "{\"a\":{\"$date\":{\"$numberLong\":\"253402300800000\"}}}"
2829
},
2930
{

src/tests/spec/json/bson-corpus/decimal128-1.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,30 @@
312312
"canonical_bson": "18000000136400000000000a5bc138938d44c64d31cc3700",
313313
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}",
314314
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"1.000000000000000000000000000000000E+999\"}}"
315+
},
316+
{
317+
"description": "Clamped zeros with a large positive exponent",
318+
"canonical_bson": "180000001364000000000000000000000000000000FE5F00",
319+
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"0E+2147483647\"}}",
320+
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"0E+6111\"}}"
321+
},
322+
{
323+
"description": "Clamped zeros with a large negative exponent",
324+
"canonical_bson": "180000001364000000000000000000000000000000000000",
325+
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"0E-2147483647\"}}",
326+
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"0E-6176\"}}"
327+
},
328+
{
329+
"description": "Clamped negative zeros with a large positive exponent",
330+
"canonical_bson": "180000001364000000000000000000000000000000FEDF00",
331+
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"-0E+2147483647\"}}",
332+
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"-0E+6111\"}}"
333+
},
334+
{
335+
"description": "Clamped negative zeros with a large negative exponent",
336+
"canonical_bson": "180000001364000000000000000000000000000000008000",
337+
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"-0E-2147483647\"}}",
338+
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"-0E-6176\"}}"
315339
}
316340
]
317341
}

0 commit comments

Comments
 (0)