Bump bson to 0.11 and use lossy utf-8 decoding for responses

Mongo can return invalid UTF-8 in bson responses:

https://jira.mongodb.org/browse/SERVER-24007

We use lossy UTF-8 decoding when parsing now.
pull/38/merge
Thijs Cadier 7 years ago
parent 8e8a02f454
commit d0b93b6bb0

@ -21,7 +21,7 @@ name = "tests"
[dependencies]
libc = "^0.2"
log = "^0.3"
bson = "^0.10"
bson = "^0.11"
[dependencies.mongoc-sys]
path = "mongoc-sys"

@ -42,6 +42,7 @@ impl Bsonc {
Ok(Bsonc{ inner: inner })
}
/// Decode a bson from the C side to a document
pub fn as_document(&self) -> Result<bson::Document> {
assert!(!self.inner.is_null());
@ -63,6 +64,28 @@ impl Bsonc {
Ok(document)
}
/// Decode a bson from the C side to a document with lossy UTF-8 decoding
pub fn as_document_utf8_lossy(&self) -> Result<bson::Document> {
assert!(!self.inner.is_null());
// This pointer should not be modified or freed
// See: http://mongoc.org/libbson/current/bson_get_data.html
let data_ptr = unsafe { bindings::bson_get_data(self.inner) };
assert!(!data_ptr.is_null());
let data_len = unsafe {
let bson = *self.inner;
bson.len
} as usize;
let mut slice = unsafe {
slice::from_raw_parts(data_ptr, data_len)
};
let document = try!(bson::decode_document_utf8_lossy(&mut slice));
Ok(document)
}
pub fn as_json(&self) -> String {
assert!(!self.inner.is_null());
let json_ptr = unsafe { bindings::bson_as_json(self.inner, ptr::null_mut()) };
@ -106,7 +129,18 @@ mod tests {
let bsonc = super::Bsonc::from_document(&document).unwrap();
let decoded = bsonc.as_document().unwrap();
assert!(decoded.contains_key("key"));
assert_eq!(decoded.get_str("key").unwrap(), "value");
}
#[test]
fn test_bsonc_from_and_as_document_invalid_utf8() {
let bytes = b"\x80\xae".to_vec();
let value = unsafe { String::from_utf8_unchecked(bytes) };
let document = doc! { "key" => value };
let bsonc = super::Bsonc::from_document(&document).unwrap();
let decoded = bsonc.as_document_utf8_lossy().unwrap();
assert_eq!(decoded.get_str("key").unwrap(), "<22><>");
}
#[test]

@ -305,7 +305,7 @@ impl<'a> Client<'a> {
};
if success == 1 {
match reply.as_document() {
match reply.as_document_utf8_lossy() {
Ok(document) => return Ok(document),
Err(error) => return Err(error.into())
}

@ -342,7 +342,7 @@ impl<'a> Collection<'a> {
};
if success == 1 {
match reply.as_document() {
match reply.as_document_utf8_lossy() {
Ok(document) => return Ok(document),
Err(error) => return Err(error.into())
}
@ -547,7 +547,7 @@ impl<'a> Collection<'a> {
};
if success == 1 {
match reply.as_document() {
match reply.as_document_utf8_lossy() {
Ok(document) => return Ok(document),
Err(error) => return Err(error.into())
}
@ -884,7 +884,7 @@ impl<'a>BulkOperation<'a> {
)
};
let document = match reply.as_document() {
let document = match reply.as_document_utf8_lossy() {
Ok(document) => document,
Err(error) => return Err(BulkOperationError{error: error.into(), reply: doc!{}})
};

@ -116,7 +116,7 @@ impl<'a> Database<'a> {
};
if success == 1 {
match reply.as_document() {
match reply.as_document_utf8_lossy() {
Ok(document) => return Ok(document),
Err(error) => return Err(error.into())
}

@ -9,7 +9,9 @@ fn test_execute_error() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri, None);
let client = pool.pop();
let collection = client.get_collection("rust_driver_test", "bulk_operation_error");
let mut collection = client.get_collection("rust_driver_test", "bulk_operation_error");
collection.drop().unwrap_or(());
let bulk_operation = collection.create_bulk_operation(None);
let result = bulk_operation.execute();
@ -24,11 +26,13 @@ fn test_basics() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri, None);
let client = pool.pop();
let collection = client.get_collection("rust_driver_test", "bulk_operation_basics");
let mut collection = client.get_collection("rust_driver_test", "bulk_operation_basics");
collection.drop().unwrap_or(());
let bulk_operation = collection.create_bulk_operation(None);
let document = doc! {"key_1" => "Value 1"};
bulk_operation.insert(&document).unwrap();
bulk_operation.insert(&document).expect("Could not insert");
assert!(bulk_operation.execute().is_ok());
let first_document = collection.find(&doc!{}, None).unwrap().next().unwrap().unwrap();
@ -43,11 +47,13 @@ fn test_utf8() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri, None);
let client = pool.pop();
let collection = client.get_collection("rust_driver_test", "bulk_operation_utf8");
let mut collection = client.get_collection("rust_driver_test", "bulk_operation_utf8");
collection.drop().unwrap_or(());
let bulk_operation = collection.create_bulk_operation(None);
let document = doc! {"key_1" => "kācaṃ śaknomyattum; nopahinasti mām."};
bulk_operation.insert(&document).unwrap();
bulk_operation.insert(&document).expect("Could not insert");
assert!(bulk_operation.execute().is_ok());
let first_document = collection.find(&doc!{}, None).unwrap().next().unwrap().unwrap();
@ -57,27 +63,6 @@ fn test_utf8() {
);
}
#[test]
fn test_utf8_invalid() {
let uri = Uri::new("mongodb://localhost:27017/").unwrap();
let pool = ClientPool::new(uri, None);
let client = pool.pop();
let collection = client.get_collection("rust_driver_test", "bulk_operation_utf8_invalid");
let bulk_operation = collection.create_bulk_operation(None);
let bytes = b"\x80\xae".to_vec();
let value = unsafe { String::from_utf8_unchecked(bytes) };
let document = doc! {"key_1" => value};
bulk_operation.insert(&document).unwrap();
assert!(bulk_operation.execute().is_ok());
let first_document = collection.find(&doc!{}, None).unwrap().next().unwrap().unwrap();
assert_eq!(
first_document.get("key_1").unwrap(),
&bson::Bson::String("𤭢".to_string())
);
}
#[test]
fn test_insert_remove_replace_update_extended() {
if env::var("SKIP_EXTENDED_BULK_OPERATION_TESTS") == Ok("true".to_string()) {

Loading…
Cancel
Save