Skip to content

Cleanup deps #137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,12 @@ decimal128 = ["decimal"]
name = "bson"

[dependencies]
byteorder = "1"
chrono = "0.4"
libc = "0.2"
rand = "0.7"
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["preserve_order"] }
linked-hash-map = "0.5.3"
hex = "0.4.2"
md5 = "0.7.0"
decimal = { version = "2.0.4", default_features = false, optional = true }
base64 = "0.12.1"
lazy_static = "1.4.0"
Expand Down
39 changes: 28 additions & 11 deletions src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ pub use self::{

use std::io::Read;

use byteorder::{LittleEndian, ReadBytesExt};
use chrono::{
offset::{LocalResult, TimeZone},
Utc,
Expand Down Expand Up @@ -79,7 +78,7 @@ where
}

fn read_string<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> Result<String> {
let len = reader.read_i32::<LittleEndian>()?;
let len = read_i32(reader)?;

// UTF-8 String must have at least 1 byte (the last 0x00).
if len < 1 {
Expand All @@ -100,7 +99,7 @@ fn read_string<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> Result<Str
};

// read the null terminator
if reader.read_u8()? != 0 {
if read_u8(reader)? != 0 {
return Err(Error::invalid_length(
len as usize,
&"contents of string longer than provided length",
Expand All @@ -114,7 +113,7 @@ fn read_cstring<R: Read + ?Sized>(reader: &mut R) -> Result<String> {
let mut v = Vec::new();

loop {
let c = reader.read_u8()?;
let c = read_u8(reader)?;
if c == 0 {
break;
}
Expand All @@ -124,14 +123,32 @@ fn read_cstring<R: Read + ?Sized>(reader: &mut R) -> Result<String> {
Ok(String::from_utf8(v)?)
}

#[inline]
fn read_u8<R: Read + ?Sized>(reader: &mut R) -> Result<u8> {
let mut buf = [0; 1];
reader.read_exact(&mut buf)?;
Ok(u8::from_le_bytes(buf))
}

#[inline]
pub(crate) fn read_i32<R: Read + ?Sized>(reader: &mut R) -> Result<i32> {
reader.read_i32::<LittleEndian>().map_err(From::from)
let mut buf = [0; 4];
reader.read_exact(&mut buf)?;
Ok(i32::from_le_bytes(buf))
}

#[inline]
fn read_i64<R: Read + ?Sized>(reader: &mut R) -> Result<i64> {
reader.read_i64::<LittleEndian>().map_err(From::from)
let mut buf = [0; 8];
reader.read_exact(&mut buf)?;
Ok(i64::from_le_bytes(buf))
}

#[inline]
fn read_f64<R: Read + ?Sized>(reader: &mut R) -> Result<f64> {
let mut buf = [0; 8];
reader.read_exact(&mut buf)?;
Ok(f64::from_le_bytes(buf))
}

/// Placeholder decoder for `Decimal128`. Reads 128 bits and just stores them, does no validation or
Expand Down Expand Up @@ -165,7 +182,7 @@ fn deserialize_array<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> Resu
"array length longer than contents",
|cursor| {
loop {
let tag = cursor.read_u8()?;
let tag = read_u8(cursor)?;
if tag == 0 {
break;
}
Expand All @@ -189,7 +206,7 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
let key = read_cstring(reader)?;

let val = match ElementType::from(tag) {
Some(ElementType::Double) => Bson::Double(reader.read_f64::<LittleEndian>()?),
Some(ElementType::Double) => Bson::Double(read_f64(reader)?),
Some(ElementType::String) => read_string(reader, utf8_lossy).map(Bson::String)?,
Some(ElementType::EmbeddedDocument) => Document::from_reader(reader).map(Bson::Document)?,
Some(ElementType::Array) => deserialize_array(reader, utf8_lossy).map(Bson::Array)?,
Expand All @@ -201,7 +218,7 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
&format!("binary length must be between 0 and {}", MAX_BSON_SIZE).as_str(),
));
}
let subtype = BinarySubtype::from(reader.read_u8()?);
let subtype = BinarySubtype::from(read_u8(reader)?);

// Skip length data in old binary.
if let BinarySubtype::BinaryOld = subtype {
Expand All @@ -225,12 +242,12 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
Some(ElementType::ObjectId) => {
let mut objid = [0; 12];
for x in &mut objid {
*x = reader.read_u8()?;
*x = read_u8(reader)?;
}
Bson::ObjectId(oid::ObjectId::with_bytes(objid))
}
Some(ElementType::Boolean) => {
let val = reader.read_u8()?;
let val = read_u8(reader)?;
if val > 1 {
return Err(Error::invalid_value(
Unexpected::Unsigned(val as u64),
Expand Down
8 changes: 4 additions & 4 deletions src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ use std::{
mem,
};

use byteorder::{ReadBytesExt, WriteBytesExt};

use chrono::{DateTime, Utc};

use linked_hash_map::{self, LinkedHashMap};
Expand Down Expand Up @@ -522,7 +520,7 @@ impl Document {
(buf.len() + mem::size_of::<i32>() + mem::size_of::<u8>()) as i32,
)?;
writer.write_all(&buf)?;
writer.write_u8(0)?;
writer.write_all(&[0])?;
Ok(())
}

Expand All @@ -544,7 +542,9 @@ impl Document {
"document length longer than contents",
|cursor| {
loop {
let tag = cursor.read_u8()?;
let mut tag_byte = [0];
cursor.read_exact(&mut tag_byte)?;
let tag = tag_byte[0];

if tag == 0 {
break;
Expand Down
24 changes: 10 additions & 14 deletions src/oid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@ use std::{
time::SystemTime,
};

use byteorder::{BigEndian, ByteOrder};

use chrono::Utc;
use hex::{self, FromHexError};

use rand::{thread_rng, Rng};

use chrono::Utc;
use lazy_static::lazy_static;

const TIMESTAMP_SIZE: usize = 4;
Expand Down Expand Up @@ -123,7 +120,10 @@ impl ObjectId {

/// Retrieves the timestamp (chrono::DateTime) from an ObjectId.
pub fn timestamp(&self) -> chrono::DateTime<Utc> {
let seconds_since_epoch = BigEndian::read_u32(&self.id);
let mut buf = [0; 4];
buf.copy_from_slice(&self.id[0..4]);
let seconds_since_epoch = u32::from_be_bytes(buf);

let naive_datetime = chrono::NaiveDateTime::from_timestamp(seconds_since_epoch as i64, 0);
let timestamp: chrono::DateTime<Utc> = chrono::DateTime::from_utc(naive_datetime, Utc);
timestamp
Expand All @@ -142,23 +142,20 @@ impl ObjectId {
// Generates a new timestamp representing the current seconds since epoch.
// Represented in Big Endian.
fn gen_timestamp() -> [u8; 4] {
let timestamp = SystemTime::now()
let timestamp: u32 = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("system clock is before 1970")
.as_secs()
.try_into()
.unwrap(); // will succeed until 2106 since timestamp is unsigned

let mut buf: [u8; 4] = [0; 4];
BigEndian::write_u32(&mut buf, timestamp);
buf
timestamp.to_be_bytes()
}

// Generate a random 5-byte array.
fn gen_process_id() -> [u8; 5] {
let rng = thread_rng().gen_range(0, MAX_U24) as u32;
let mut buf: [u8; 5] = [0; 5];
BigEndian::write_u32(&mut buf, rng);
buf[0..4].copy_from_slice(&rng.to_be_bytes());
buf
}

Expand All @@ -173,8 +170,7 @@ impl ObjectId {
// Convert usize to writable u64, then extract the first three bytes.
let u_int = u as u64;

let mut buf: [u8; 8] = [0; 8];
BigEndian::write_u64(&mut buf, u_int);
let buf = u_int.to_be_bytes();
let buf_u24: [u8; 3] = [buf[5], buf[6], buf[7]];
buf_u24
}
Expand Down Expand Up @@ -207,7 +203,7 @@ fn count_generated_is_big_endian() {
let mut buf: [u8; 4] = [0; 4];
buf[1..=COUNTER_SIZE].clone_from_slice(&count_bytes[..COUNTER_SIZE]);

let count = BigEndian::read_u32(&buf);
let count = u32::from_be_bytes(buf);
assert_eq!(start as u32, count);

// Test OID formats count correctly as big endian
Expand Down
30 changes: 19 additions & 11 deletions src/ser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ pub use self::{

use std::{io::Write, mem};

use byteorder::{LittleEndian, WriteBytesExt};
use chrono::Timelike;

#[cfg(feature = "decimal128")]
Expand All @@ -43,31 +42,40 @@ use crate::{
use ::serde::Serialize;

fn write_string<W: Write + ?Sized>(writer: &mut W, s: &str) -> Result<()> {
writer.write_i32::<LittleEndian>(s.len() as i32 + 1)?;
writer.write_all(&(s.len() as i32 + 1).to_le_bytes())?;
writer.write_all(s.as_bytes())?;
writer.write_u8(0)?;
writer.write_all(b"\0")?;
Ok(())
}

fn write_cstring<W: Write + ?Sized>(writer: &mut W, s: &str) -> Result<()> {
writer.write_all(s.as_bytes())?;
writer.write_u8(0)?;
writer.write_all(b"\0")?;
Ok(())
}

#[inline]
pub(crate) fn write_i32<W: Write + ?Sized>(writer: &mut W, val: i32) -> Result<()> {
writer.write_i32::<LittleEndian>(val).map_err(From::from)
writer
.write_all(&val.to_le_bytes())
.map(|_| ())
.map_err(From::from)
}

#[inline]
fn write_i64<W: Write + ?Sized>(writer: &mut W, val: i64) -> Result<()> {
writer.write_i64::<LittleEndian>(val).map_err(From::from)
writer
.write_all(&val.to_le_bytes())
.map(|_| ())
.map_err(From::from)
}

#[inline]
fn write_f64<W: Write + ?Sized>(writer: &mut W, val: f64) -> Result<()> {
writer.write_f64::<LittleEndian>(val).map_err(From::from)
writer
.write_all(&val.to_le_bytes())
.map(|_| ())
.map_err(From::from)
}

#[cfg(feature = "decimal128")]
Expand All @@ -88,7 +96,7 @@ fn serialize_array<W: Write + ?Sized>(writer: &mut W, arr: &[Bson]) -> Result<()
(buf.len() + mem::size_of::<i32>() + mem::size_of::<u8>()) as i32,
)?;
writer.write_all(&buf)?;
writer.write_u8(0)?;
writer.write_all(b"\0")?;
Ok(())
}

Expand All @@ -97,7 +105,7 @@ pub(crate) fn serialize_bson<W: Write + ?Sized>(
key: &str,
val: &Bson,
) -> Result<()> {
writer.write_u8(val.element_type() as u8)?;
writer.write_all(&[val.element_type() as u8])?;
write_cstring(writer, key)?;

match *val {
Expand All @@ -106,7 +114,7 @@ pub(crate) fn serialize_bson<W: Write + ?Sized>(
Bson::Array(ref v) => serialize_array(writer, &v),
Bson::Document(ref v) => v.to_writer(writer),
Bson::Boolean(v) => writer
.write_u8(if v { 0x01 } else { 0x00 })
.write_all(&[if v { 0x01 } else { 0x00 }])
.map_err(From::from),
Bson::RegularExpression(Regex {
ref pattern,
Expand Down Expand Up @@ -139,7 +147,7 @@ pub(crate) fn serialize_bson<W: Write + ?Sized>(
};

write_i32(writer, len as i32)?;
writer.write_u8(From::from(subtype))?;
writer.write_all(&[subtype.into()])?;

if let BinarySubtype::BinaryOld = subtype {
write_i32(writer, len as i32 - 4)?;
Expand Down
9 changes: 4 additions & 5 deletions src/tests/modules/serializer_deserializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use crate::{
Regex,
Timestamp,
};
use byteorder::{LittleEndian, WriteBytesExt};
use chrono::{offset::TimeZone, Utc};
use serde_json::json;

Expand Down Expand Up @@ -333,16 +332,16 @@ fn test_serialize_deserialize_symbol() {
#[test]
fn test_deserialize_utc_date_time_overflows() {
let _guard = LOCK.run_concurrently();
let t = 1_530_492_218 * 1_000 + 999;
let t: i64 = 1_530_492_218 * 1_000 + 999;

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

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

let deserialized = Document::from_reader(&mut Cursor::new(raw)).unwrap();

Expand Down