Skip to content

Commit

Permalink
[#64] Reverted saturating usec of UTC time
Browse files Browse the repository at this point in the history
  • Loading branch information
zonyitoo committed Jul 3, 2018
1 parent bee5b02 commit a94291b
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ fn decode_bson<R: Read + ?Sized>(reader: &mut R, tag: u8, utf8_lossy: bool) -> D
// The int64 is UTC milliseconds since the Unix epoch.
let time = read_i64(reader)?;

match Utc.timestamp_opt(time / 1000, ((time % 1000) as u32).saturating_mul(1_000_000)) {
match Utc.timestamp_opt(time / 1000, ((time % 1000) as u32) * 1_000_000) {
LocalResult::None => Err(DecoderError::InvalidTimestamp(time)),
LocalResult::Ambiguous(..) => Err(DecoderError::AmbiguousTimestamp(time)),
LocalResult::Single(t) => Ok(Bson::UtcDatetime(t)),
Expand Down
2 changes: 1 addition & 1 deletion src/encoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ fn encode_bson<W: Write + ?Sized>(writer: &mut W, key: &str, val: &Bson) -> Enco
writer.write_u8(From::from(subtype))?;
writer.write_all(data).map_err(From::from)
}
&Bson::UtcDatetime(ref v) => write_i64(writer, (v.timestamp() * 1000) + (v.nanosecond() / 1000000) as i64),
&Bson::UtcDatetime(ref v) => write_i64(writer, (v.timestamp() * 1000) + (v.nanosecond() / 1_000_000) as i64),
&Bson::Null => Ok(()),
&Bson::Symbol(ref v) => write_string(writer, &v),
}
Expand Down
1 change: 1 addition & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[macro_use(bson, doc)]
extern crate bson;
extern crate byteorder;
extern crate chrono;
extern crate hex;

Expand Down
25 changes: 22 additions & 3 deletions tests/modules/encoder_decoder.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use bson::{decode_document, encode_document, Bson, decode_document_utf8_lossy};
use bson::oid::ObjectId;
use bson::spec::BinarySubtype;
use chrono::Utc;
use bson::{decode_document, decode_document_utf8_lossy, encode_document, Bson};
use byteorder::{LittleEndian, WriteBytesExt};
use chrono::offset::TimeZone;
use std::io::Cursor;
use chrono::Utc;
use std::io::{Cursor, Write};

#[test]
fn test_encode_decode_floating_point() {
Expand Down Expand Up @@ -277,3 +278,21 @@ fn test_encode_decode_symbol() {
let decoded = decode_document(&mut Cursor::new(buf)).unwrap();
assert_eq!(decoded, doc);
}

#[test]
fn test_decode_utc_date_time_overflows() {
let t = 1530492218 * 1_000 + 999;

let mut raw0 = vec![0x09, b'A', 0x00];
raw0.write_i64::<LittleEndian>(t).unwrap();

let mut raw = vec![];
raw.write_i32::<LittleEndian>((raw0.len() + 4 + 1) as i32).unwrap();
raw.write_all(&raw0).unwrap();
raw.write_u8(0).unwrap();

let decoded = decode_document(&mut Cursor::new(raw)).unwrap();

let expected = doc! { "A" => Utc.timestamp(1530492218, 999 * 1_000_000)};
assert_eq!(decoded, expected);
}

0 comments on commit a94291b

Please sign in to comment.