@@ -44,11 +44,41 @@ use crate::{
4444 Decimal128 ,
4545} ;
4646
47- use :: serde:: de:: { self , Error as _} ;
47+ use :: serde:: {
48+ de:: { Error as _, Unexpected } ,
49+ Deserialize ,
50+ } ;
4851
4952const MAX_BSON_SIZE : i32 = 16 * 1024 * 1024 ;
53+ pub ( crate ) const MIN_BSON_DOCUMENT_SIZE : i32 = 4 + 1 ; // 4 bytes for length, one byte for null terminator
54+ const MIN_BSON_STRING_SIZE : i32 = 4 + 1 ; // 4 bytes for length, one byte for null terminator
55+ const MIN_CODE_WITH_SCOPE_SIZE : i32 = 4 + MIN_BSON_STRING_SIZE + MIN_BSON_DOCUMENT_SIZE ;
56+
57+ /// Run the provided closure, ensuring that over the course of its execution, exactly `length` bytes
58+ /// were read from the reader.
59+ pub ( crate ) fn ensure_read_exactly < F , R > (
60+ reader : & mut R ,
61+ length : usize ,
62+ error_message : & str ,
63+ func : F ,
64+ ) -> Result < ( ) >
65+ where
66+ F : FnOnce ( & mut std:: io:: Cursor < Vec < u8 > > ) -> Result < ( ) > ,
67+ R : Read + ?Sized ,
68+ {
69+ let mut buf = vec ! [ 0u8 ; length] ;
70+ reader. read_exact ( & mut buf) ?;
71+ let mut cursor = std:: io:: Cursor :: new ( buf) ;
72+
73+ func ( & mut cursor) ?;
74+
75+ if cursor. position ( ) != length as u64 {
76+ return Err ( Error :: invalid_length ( length, & error_message) ) ;
77+ }
78+ Ok ( ( ) )
79+ }
5080
51- fn read_string < R : Read + ?Sized > ( reader : & mut R , utf8_lossy : bool ) -> crate :: de :: Result < String > {
81+ fn read_string < R : Read + ?Sized > ( reader : & mut R , utf8_lossy : bool ) -> Result < String > {
5282 let len = reader. read_i32 :: < LittleEndian > ( ) ?;
5383
5484 // UTF-8 String must have at least 1 byte (the last 0x00).
@@ -68,12 +98,19 @@ fn read_string<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> crate::de:
6898 reader. take ( len as u64 - 1 ) . read_to_string ( & mut s) ?;
6999 s
70100 } ;
71- reader. read_u8 ( ) ?; // The last 0x00
101+
102+ // read the null terminator
103+ if reader. read_u8 ( ) ? != 0 {
104+ return Err ( Error :: invalid_length (
105+ len as usize ,
106+ & "contents of string longer than provided length" ,
107+ ) ) ;
108+ }
72109
73110 Ok ( s)
74111}
75112
76- fn read_cstring < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < String > {
113+ fn read_cstring < R : Read + ?Sized > ( reader : & mut R ) -> Result < String > {
77114 let mut v = Vec :: new ( ) ;
78115
79116 loop {
@@ -88,28 +125,28 @@ fn read_cstring<R: Read + ?Sized>(reader: &mut R) -> crate::de::Result<String> {
88125}
89126
90127#[ inline]
91- pub ( crate ) fn read_i32 < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < i32 > {
128+ pub ( crate ) fn read_i32 < R : Read + ?Sized > ( reader : & mut R ) -> Result < i32 > {
92129 reader. read_i32 :: < LittleEndian > ( ) . map_err ( From :: from)
93130}
94131
95132#[ inline]
96- fn read_i64 < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < i64 > {
133+ fn read_i64 < R : Read + ?Sized > ( reader : & mut R ) -> Result < i64 > {
97134 reader. read_i64 :: < LittleEndian > ( ) . map_err ( From :: from)
98135}
99136
100137/// Placeholder decoder for `Decimal128`. Reads 128 bits and just stores them, does no validation or
101138/// parsing.
102139#[ cfg( not( feature = "decimal128" ) ) ]
103140#[ inline]
104- fn read_f128 < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < Decimal128 > {
141+ fn read_f128 < R : Read + ?Sized > ( reader : & mut R ) -> Result < Decimal128 > {
105142 let mut buf = [ 0u8 ; 128 / 8 ] ;
106143 reader. read_exact ( & mut buf) ?;
107144 Ok ( Decimal128 { bytes : buf } )
108145}
109146
110147#[ cfg( feature = "decimal128" ) ]
111148#[ inline]
112- fn read_f128 < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < Decimal128 > {
149+ fn read_f128 < R : Read + ?Sized > ( reader : & mut R ) -> Result < Decimal128 > {
113150 use std:: mem;
114151
115152 let mut local_buf: [ u8 ; 16 ] = unsafe { mem:: MaybeUninit :: uninit ( ) . assume_init ( ) } ;
@@ -118,24 +155,27 @@ fn read_f128<R: Read + ?Sized>(reader: &mut R) -> crate::de::Result<Decimal128>
118155 Ok ( val)
119156}
120157
121- fn deserialize_array < R : Read + ?Sized > (
122- reader : & mut R ,
123- utf8_lossy : bool ,
124- ) -> crate :: de:: Result < Array > {
158+ fn deserialize_array < R : Read + ?Sized > ( reader : & mut R , utf8_lossy : bool ) -> Result < Array > {
125159 let mut arr = Array :: new ( ) ;
126-
127- // disregard the length: using Read::take causes infinite type recursion
128- read_i32 ( reader) ?;
129-
130- loop {
131- let tag = reader. read_u8 ( ) ?;
132- if tag == 0 {
133- break ;
134- }
135-
136- let ( _, val) = deserialize_bson_kvp ( reader, tag, utf8_lossy) ?;
137- arr. push ( val)
138- }
160+ let length = read_i32 ( reader) ?;
161+
162+ ensure_read_exactly (
163+ reader,
164+ ( length as usize ) - 4 ,
165+ "array length longer than contents" ,
166+ |cursor| {
167+ loop {
168+ let tag = cursor. read_u8 ( ) ?;
169+ if tag == 0 {
170+ break ;
171+ }
172+
173+ let ( _, val) = deserialize_bson_kvp ( cursor, tag, utf8_lossy) ?;
174+ arr. push ( val)
175+ }
176+ Ok ( ( ) )
177+ } ,
178+ ) ?;
139179
140180 Ok ( arr)
141181}
@@ -144,7 +184,7 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
144184 reader : & mut R ,
145185 tag : u8 ,
146186 utf8_lossy : bool ,
147- ) -> crate :: de :: Result < ( String , Bson ) > {
187+ ) -> Result < ( String , Bson ) > {
148188 use spec:: ElementType ;
149189 let key = read_cstring ( reader) ?;
150190
@@ -165,7 +205,15 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
165205
166206 // Skip length data in old binary.
167207 if let BinarySubtype :: BinaryOld = subtype {
168- read_i32 ( reader) ?;
208+ let data_len = read_i32 ( reader) ?;
209+
210+ if data_len + 4 != len {
211+ return Err ( Error :: invalid_length (
212+ data_len as usize ,
213+ & "0x02 length did not match top level binary length" ,
214+ ) ) ;
215+ }
216+
169217 len -= 4 ;
170218 }
171219
@@ -181,7 +229,17 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
181229 }
182230 Bson :: ObjectId ( oid:: ObjectId :: with_bytes ( objid) )
183231 }
184- Some ( ElementType :: Boolean ) => Bson :: Boolean ( reader. read_u8 ( ) ? != 0 ) ,
232+ Some ( ElementType :: Boolean ) => {
233+ let val = reader. read_u8 ( ) ?;
234+ if val > 1 {
235+ return Err ( Error :: invalid_value (
236+ Unexpected :: Unsigned ( val as u64 ) ,
237+ & "boolean must be stored as 0 or 1" ,
238+ ) ) ;
239+ }
240+
241+ Bson :: Boolean ( val != 0 )
242+ }
185243 Some ( ElementType :: Null ) => Bson :: Null ,
186244 Some ( ElementType :: RegularExpression ) => {
187245 let pattern = read_cstring ( reader) ?;
@@ -198,12 +256,29 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
198256 read_string ( reader, utf8_lossy) . map ( Bson :: JavaScriptCode ) ?
199257 }
200258 Some ( ElementType :: JavaScriptCodeWithScope ) => {
201- // disregard the length:
202- // using Read::take causes infinite type recursion
203- read_i32 ( reader) ?;
259+ let length = read_i32 ( reader) ?;
260+ if length < MIN_CODE_WITH_SCOPE_SIZE {
261+ return Err ( Error :: invalid_length (
262+ length as usize ,
263+ & format ! (
264+ "code with scope length must be at least {}" ,
265+ MIN_CODE_WITH_SCOPE_SIZE
266+ )
267+ . as_str ( ) ,
268+ ) ) ;
269+ } else if length > MAX_BSON_SIZE {
270+ return Err ( Error :: invalid_length (
271+ length as usize ,
272+ & "code with scope length too large" ,
273+ ) ) ;
274+ }
275+
276+ let mut buf = vec ! [ 0u8 ; ( length - 4 ) as usize ] ;
277+ reader. read_exact ( & mut buf) ?;
204278
205- let code = read_string ( reader, utf8_lossy) ?;
206- let scope = Document :: from_reader ( reader) ?;
279+ let mut slice = buf. as_slice ( ) ;
280+ let code = read_string ( & mut slice, utf8_lossy) ?;
281+ let scope = Document :: from_reader ( & mut slice) ?;
207282 Bson :: JavaScriptCodeWithScope ( JavaScriptCodeWithScope { code, scope } )
208283 }
209284 Some ( ElementType :: Int32 ) => read_i32 ( reader) . map ( Bson :: Int32 ) ?,
@@ -256,10 +331,10 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
256331}
257332
258333/// Decode a BSON `Value` into a `T` Deserializable.
259- pub fn from_bson < ' de , T > ( bson : Bson ) -> crate :: de :: Result < T >
334+ pub fn from_bson < ' de , T > ( bson : Bson ) -> Result < T >
260335where
261- T : de :: Deserialize < ' de > ,
336+ T : Deserialize < ' de > ,
262337{
263338 let de = Deserializer :: new ( bson) ;
264- de :: Deserialize :: deserialize ( de)
339+ Deserialize :: deserialize ( de)
265340}
0 commit comments