Skip to content

Commit 2f453eb

Browse files
authored
RUST-217 Rephrase unsupported/corrupt BSON messages (#170)
1 parent 4689d15 commit 2f453eb

File tree

2 files changed

+53
-47
lines changed

2 files changed

+53
-47
lines changed

src/decoder/error.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use serde::de::{self, Expected, Unexpected};
88
pub enum DecoderError {
99
IoError(io::Error),
1010
FromUtf8Error(string::FromUtf8Error),
11-
UnrecognizedElementType(u8),
11+
UnrecognizedDocumentElementType { key: String, element_type: u8 },
1212
InvalidArrayKey(usize, String),
1313
// A field was expected, but none was found.
1414
ExpectedField(&'static str),
@@ -53,9 +53,14 @@ impl fmt::Display for DecoderError {
5353
match *self {
5454
DecoderError::IoError(ref inner) => inner.fmt(fmt),
5555
DecoderError::FromUtf8Error(ref inner) => inner.fmt(fmt),
56-
DecoderError::UnrecognizedElementType(tag) => {
57-
write!(fmt, "unrecognized element type `{}`", tag)
58-
}
56+
DecoderError::UnrecognizedDocumentElementType {
57+
ref key,
58+
element_type,
59+
} => write!(
60+
fmt,
61+
"unrecognized element type for key \"{}\": `{}`",
62+
key, element_type
63+
),
5964
DecoderError::InvalidArrayKey(ref want, ref got) => {
6065
write!(fmt, "invalid array key: expected `{}`, got `{}`", want, got)
6166
}
@@ -92,7 +97,7 @@ impl error::Error for DecoderError {
9297
#[allow(deprecated)]
9398
inner.description()
9499
}
95-
DecoderError::UnrecognizedElementType(_) => "unrecognized element type",
100+
DecoderError::UnrecognizedDocumentElementType { .. } => "unrecognized element type",
96101
DecoderError::InvalidArrayKey(..) => "invalid array key",
97102
DecoderError::ExpectedField(_) => "expected a field",
98103
DecoderError::UnknownField(_) => "found an unknown field",

src/decoder/mod.rs

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,7 @@ pub fn decode_document<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<Docume
123123
break;
124124
}
125125

126-
let key = read_cstring(reader)?;
127-
let val = decode_bson(reader, tag, false)?;
128-
126+
let (key, val) = decode_bson_kvp(reader, tag, false)?;
129127
doc.insert(key, val);
130128
}
131129

@@ -146,8 +144,7 @@ pub fn decode_document_utf8_lossy<R: Read + ?Sized>(reader: &mut R) -> DecoderRe
146144
break;
147145
}
148146

149-
let key = read_cstring(reader)?;
150-
let val = decode_bson(reader, tag, true)?;
147+
let (key, val) = decode_bson_kvp(reader, tag, true)?;
151148

152149
doc.insert(key, val);
153150
}
@@ -167,8 +164,7 @@ fn decode_array<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> DecoderRe
167164
break;
168165
}
169166

170-
// check that the key is as expected
171-
let key = read_cstring(reader)?;
167+
let (key, val) = decode_bson_kvp(reader, tag, utf8_lossy)?;
172168
match key.parse::<usize>() {
173169
Err(..) => return Err(DecoderError::InvalidArrayKey(arr.len(), key)),
174170
Ok(idx) => {
@@ -177,24 +173,25 @@ fn decode_array<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> DecoderRe
177173
}
178174
}
179175
}
180-
181-
let val = decode_bson(reader, tag, utf8_lossy)?;
182176
arr.push(val)
183177
}
184178

185179
Ok(arr)
186180
}
187181

188-
fn decode_bson<R: Read + ?Sized>(reader: &mut R, tag: u8, utf8_lossy: bool) -> DecoderResult<Bson> {
182+
fn decode_bson_kvp<R: Read + ?Sized>(
183+
reader: &mut R,
184+
tag: u8,
185+
utf8_lossy: bool,
186+
) -> DecoderResult<(String, Bson)> {
189187
use spec::ElementType;
188+
let key = read_cstring(reader)?;
190189

191-
match ElementType::from(tag) {
192-
Some(ElementType::FloatingPoint) => {
193-
Ok(Bson::FloatingPoint(reader.read_f64::<LittleEndian>()?))
194-
}
195-
Some(ElementType::Utf8String) => read_string(reader, utf8_lossy).map(Bson::String),
196-
Some(ElementType::EmbeddedDocument) => decode_document(reader).map(Bson::Document),
197-
Some(ElementType::Array) => decode_array(reader, utf8_lossy).map(Bson::Array),
190+
let val = match ElementType::from(tag) {
191+
Some(ElementType::FloatingPoint) => Bson::FloatingPoint(reader.read_f64::<LittleEndian>()?),
192+
Some(ElementType::Utf8String) => read_string(reader, utf8_lossy).map(Bson::String)?,
193+
Some(ElementType::EmbeddedDocument) => decode_document(reader).map(Bson::Document)?,
194+
Some(ElementType::Array) => decode_array(reader, utf8_lossy).map(Bson::Array)?,
198195
Some(ElementType::Binary) => {
199196
let len = read_i32(reader)?;
200197
if len < 0 || len > MAX_BSON_SIZE {
@@ -206,24 +203,24 @@ fn decode_bson<R: Read + ?Sized>(reader: &mut R, tag: u8, utf8_lossy: bool) -> D
206203
let subtype = BinarySubtype::from(reader.read_u8()?);
207204
let mut bytes = Vec::with_capacity(len as usize);
208205
reader.take(len as u64).read_to_end(&mut bytes)?;
209-
Ok(Bson::Binary(Binary { subtype, bytes }))
206+
Bson::Binary(Binary { subtype, bytes })
210207
}
211208
Some(ElementType::ObjectId) => {
212209
let mut objid = [0; 12];
213210
for x in &mut objid {
214211
*x = reader.read_u8()?;
215212
}
216-
Ok(Bson::ObjectId(oid::ObjectId::with_bytes(objid)))
213+
Bson::ObjectId(oid::ObjectId::with_bytes(objid))
217214
}
218-
Some(ElementType::Boolean) => Ok(Bson::Boolean(reader.read_u8()? != 0)),
219-
Some(ElementType::NullValue) => Ok(Bson::Null),
215+
Some(ElementType::Boolean) => Bson::Boolean(reader.read_u8()? != 0),
216+
Some(ElementType::NullValue) => Bson::Null,
220217
Some(ElementType::RegularExpression) => {
221218
let pattern = read_cstring(reader)?;
222219
let options = read_cstring(reader)?;
223-
Ok(Bson::Regex(Regex { pattern, options }))
220+
Bson::Regex(Regex { pattern, options })
224221
}
225222
Some(ElementType::JavaScriptCode) => {
226-
read_string(reader, utf8_lossy).map(Bson::JavaScriptCode)
223+
read_string(reader, utf8_lossy).map(Bson::JavaScriptCode)?
227224
}
228225
Some(ElementType::JavaScriptCodeWithScope) => {
229226
// disregard the length:
@@ -232,15 +229,12 @@ fn decode_bson<R: Read + ?Sized>(reader: &mut R, tag: u8, utf8_lossy: bool) -> D
232229

233230
let code = read_string(reader, utf8_lossy)?;
234231
let scope = decode_document(reader)?;
235-
Ok(Bson::JavaScriptCodeWithScope(JavaScriptCodeWithScope {
236-
code,
237-
scope,
238-
}))
232+
Bson::JavaScriptCodeWithScope(JavaScriptCodeWithScope { code, scope })
239233
}
240-
Some(ElementType::Integer32Bit) => read_i32(reader).map(Bson::I32),
241-
Some(ElementType::Integer64Bit) => read_i64(reader).map(Bson::I64),
234+
Some(ElementType::Integer32Bit) => read_i32(reader).map(Bson::I32)?,
235+
Some(ElementType::Integer64Bit) => read_i64(reader).map(Bson::I64)?,
242236
Some(ElementType::TimeStamp) => {
243-
read_i64(reader).map(|val| Bson::TimeStamp(TimeStamp::from_le_i64(val)))
237+
read_i64(reader).map(|val| Bson::TimeStamp(TimeStamp::from_le_i64(val)))?
244238
}
245239
Some(ElementType::UtcDatetime) => {
246240
// The int64 is UTC milliseconds since the Unix epoch.
@@ -255,28 +249,35 @@ fn decode_bson<R: Read + ?Sized>(reader: &mut R, tag: u8, utf8_lossy: bool) -> D
255249
};
256250

257251
match Utc.timestamp_opt(sec, (msec as u32) * 1_000_000) {
258-
LocalResult::None => Err(DecoderError::InvalidTimestamp(time)),
259-
LocalResult::Ambiguous(..) => Err(DecoderError::AmbiguousTimestamp(time)),
260-
LocalResult::Single(t) => Ok(Bson::UtcDatetime(t)),
252+
LocalResult::None => return Err(DecoderError::InvalidTimestamp(time)),
253+
LocalResult::Ambiguous(..) => return Err(DecoderError::AmbiguousTimestamp(time)),
254+
LocalResult::Single(t) => Bson::UtcDatetime(t),
261255
}
262256
}
263-
Some(ElementType::Symbol) => read_string(reader, utf8_lossy).map(Bson::Symbol),
257+
Some(ElementType::Symbol) => read_string(reader, utf8_lossy).map(Bson::Symbol)?,
264258
#[cfg(feature = "decimal128")]
265-
Some(ElementType::Decimal128Bit) => read_f128(reader).map(Bson::Decimal128),
266-
Some(ElementType::Undefined) => Ok(Bson::Undefined),
259+
Some(ElementType::Decimal128Bit) => read_f128(reader).map(Bson::Decimal128)?,
260+
Some(ElementType::Undefined) => Bson::Undefined,
267261
Some(ElementType::DbPointer) => {
268262
let namespace = read_string(reader, utf8_lossy)?;
269263
let mut objid = [0; 12];
270264
reader.read_exact(&mut objid)?;
271-
Ok(Bson::DbPointer(DbPointer {
265+
Bson::DbPointer(DbPointer {
272266
namespace,
273267
id: oid::ObjectId::with_bytes(objid),
274-
}))
268+
})
275269
}
276-
Some(ElementType::MaxKey) => Ok(Bson::MaxKey),
277-
Some(ElementType::MinKey) => Ok(Bson::MinKey),
278-
None => Err(DecoderError::UnrecognizedElementType(tag)),
279-
}
270+
Some(ElementType::MaxKey) => Bson::MaxKey,
271+
Some(ElementType::MinKey) => Bson::MinKey,
272+
None => {
273+
return Err(DecoderError::UnrecognizedDocumentElementType {
274+
key,
275+
element_type: tag,
276+
})
277+
}
278+
};
279+
280+
Ok((key, val))
280281
}
281282

282283
/// Decode a BSON `Value` into a `T` Deserializable.

0 commit comments

Comments
 (0)