@@ -225,61 +225,65 @@ func (d *decoder) readDocTo(out reflect.Value) {
225225 panic ("Unsupported document type for unmarshalling: " + out .Type ().String ())
226226 }
227227
228- end := int (d .readInt32 ())
229- end += d .i - 4
230- if end <= d .i || end > len (d .in ) || d .in [end - 1 ] != '\x00' {
231- corrupted ()
232- }
233- for d .in [d .i ] != '\x00' {
234- kind := d .readByte ()
235- name := d .readCStr ()
236- if d .i >= end {
228+ if outt == typeRaw {
229+ d .skipDoc ()
230+ } else {
231+ end := int (d .readInt32 ())
232+ end += d .i - 4
233+ if end <= d .i || end > len (d .in ) || d .in [end - 1 ] != '\x00' {
237234 corrupted ()
238235 }
236+ for d .in [d .i ] != '\x00' {
237+ kind := d .readByte ()
238+ name := d .readCStr ()
239+ if d .i >= end {
240+ corrupted ()
241+ }
239242
240- switch outk {
241- case reflect .Map :
242- e := reflect .New (elemType ).Elem ()
243- if d .readElemTo (e , kind ) {
244- k := reflect .ValueOf (name )
245- if convertKey {
246- k = k .Convert (keyType )
243+ switch outk {
244+ case reflect .Map :
245+ e := reflect .New (elemType ).Elem ()
246+ if d .readElemTo (e , kind ) {
247+ k := reflect .ValueOf (name )
248+ if convertKey {
249+ k = k .Convert (keyType )
250+ }
251+ out .SetMapIndex (k , e )
247252 }
248- out .SetMapIndex (k , e )
249- }
250- case reflect .Struct :
251- if outt == typeRaw {
252- d .dropElem (kind )
253- } else {
254- if info , ok := fieldsMap [name ]; ok {
255- if info .Inline == nil {
256- d .readElemTo (out .Field (info .Num ), kind )
253+ case reflect .Struct :
254+ if outt == typeRaw {
255+ d .dropElem (kind )
256+ } else {
257+ if info , ok := fieldsMap [name ]; ok {
258+ if info .Inline == nil {
259+ d .readElemTo (out .Field (info .Num ), kind )
260+ } else {
261+ d .readElemTo (out .FieldByIndex (info .Inline ), kind )
262+ }
263+ } else if inlineMap .IsValid () {
264+ if inlineMap .IsNil () {
265+ inlineMap .Set (reflect .MakeMap (inlineMap .Type ()))
266+ }
267+ e := reflect .New (elemType ).Elem ()
268+ if d .readElemTo (e , kind ) {
269+ inlineMap .SetMapIndex (reflect .ValueOf (name ), e )
270+ }
257271 } else {
258- d .readElemTo ( out . FieldByIndex ( info . Inline ), kind )
272+ d .dropElem ( kind )
259273 }
260- } else if inlineMap .IsValid () {
261- if inlineMap .IsNil () {
262- inlineMap .Set (reflect .MakeMap (inlineMap .Type ()))
263- }
264- e := reflect .New (elemType ).Elem ()
265- if d .readElemTo (e , kind ) {
266- inlineMap .SetMapIndex (reflect .ValueOf (name ), e )
267- }
268- } else {
269- d .dropElem (kind )
270274 }
275+ case reflect .Slice :
271276 }
272- case reflect .Slice :
273- }
274277
275- if d .i >= end {
278+ if d .i >= end {
279+ corrupted ()
280+ }
281+ }
282+ d .i ++ // '\x00'
283+ if d .i != end {
276284 corrupted ()
277285 }
278286 }
279- d .i ++ // '\x00'
280- if d .i != end {
281- corrupted ()
282- }
283287 d .docType = docType
284288
285289 if outt == typeRaw {
@@ -431,7 +435,40 @@ func (d *decoder) readDocWith(f func(kind byte, name string)) {
431435var blackHole = settableValueOf (struct {}{})
432436
433437func (d * decoder ) dropElem (kind byte ) {
434- d .readElemTo (blackHole , kind )
438+ switch kind {
439+ case 0x01 , 0x09 , 0x11 , 0x12 : // utc datetime, timestamp, int64
440+ d .i += 8
441+ case 0x02 , 0x0D , 0x0E : // string, javascript, symbol
442+ size := int (d .readInt32 ())
443+ if size <= 0 || d .in [d .i + size - 1 ] != 0x00 {
444+ corrupted ()
445+ }
446+ d .i += size
447+ case 0x03 , 0x04 : // doc, array
448+ d .skipDoc ()
449+ case 0x05 : // binary
450+ size := int (d .readInt32 ())
451+ d .i += size + 1 // + 1 for the subtype
452+ case 0x06 : // undefined
453+ case 0x07 : // objectID
454+ d .i += 12
455+ case 0x08 :
456+ d .i ++
457+ case 0x0A : // null
458+ case 0x0B : // regex
459+ d .readCStr ()
460+ d .readCStr ()
461+ case 0x0C : // dbpointer
462+ size := int (d .readInt32 ())
463+ d .i += size + 12
464+ case 0x10 : // int32
465+ d .i += 4
466+ case 0x13 : // decimal
467+ d .i += 16
468+ case 0xFF , 0x7F : //min key, max key
469+ default :
470+ d .readElemTo (blackHole , kind )
471+ }
435472}
436473
437474// Attempt to decode an element from the document and put it into out.
@@ -461,11 +498,11 @@ func (d *decoder) readElemTo(out reflect.Value, kind byte) (good bool) {
461498 case typeRawDocElem :
462499 out .Set (d .readRawDocElems (outt ))
463500 default :
464- d .readDocTo ( blackHole )
501+ d .skipDoc ( )
465502 }
466503 return true
467504 }
468- d .readDocTo ( blackHole )
505+ d .skipDoc ( )
469506 return true
470507 }
471508
@@ -748,6 +785,15 @@ func (d *decoder) readElemTo(out reflect.Value, kind byte) (good bool) {
748785// --------------------------------------------------------------------------
749786// Parsers of basic types.
750787
788+ func (d * decoder ) skipDoc () {
789+ end := int (d .readInt32 ())
790+ end += d .i - 4
791+ if end <= d .i || end > len (d .in ) || d .in [end - 1 ] != '\x00' {
792+ corrupted ()
793+ }
794+ d .i = end
795+ }
796+
751797func (d * decoder ) readRegEx () RegEx {
752798 re := RegEx {}
753799 re .Pattern = d .readCStr ()
0 commit comments