2828package bson
2929
3030import (
31- "errors"
3231 "fmt"
3332 "io"
3433 "math"
@@ -38,6 +37,8 @@ import (
3837 "sync"
3938 "time"
4039
40+ "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
41+
4142 "go.mongodb.org/mongo-driver/bson"
4243 "go.mongodb.org/mongo-driver/bson/bsontype"
4344 "go.mongodb.org/mongo-driver/bson/primitive"
@@ -404,104 +405,11 @@ func (d *decoder) readSliceDoc(t reflect.Type) interface{} {
404405}
405406
406407func BSONElementSize (kind bsontype.Type , offset int , buffer []byte ) (int , error ) {
407- switch kind {
408- case ElementFloat64 : // Float64
409- return 8 , nil
410- case ElementJavaScriptWithoutScope : // JavaScript without scope
411- fallthrough
412- case ElementSymbol : // Symbol
413- fallthrough
414- case ElementString : // UTF-8 string
415- size , err := getSize (offset , buffer )
416- if err != nil {
417- return 0 , err
418- }
419- if size < 1 {
420- return 0 , errors .New ("String size can't be less then one byte" )
421- }
422- size += 4
423- if offset + size > len (buffer ) {
424- return 0 , io .ErrUnexpectedEOF
425- }
426- if buffer [offset + size - 1 ] != 0 {
427- return 0 , errors .New ("Invalid string: non zero-terminated" )
428- }
429- return size , nil
430- case ElementArray : // Array
431- fallthrough
432- case ElementDocument : // Document
433- size , err := getSize (offset , buffer )
434- if err != nil {
435- return 0 , err
436- }
437- if size < 5 {
438- return 0 , errors .New ("Declared document size is too small" )
439- }
440- return size , nil
441- case ElementBinary : // Binary
442- size , err := getSize (offset , buffer )
443- if err != nil {
444- return 0 , err
445- }
446- if size < 0 {
447- return 0 , errors .New ("Binary data size can't be negative" )
448- }
449- return size + 5 , nil
450- case Element06 : // Undefined (obsolete, but still seen in the wild)
451- return 0 , nil
452- case ElementObjectId : // ObjectId
453- return 12 , nil
454- case ElementBool : // Bool
455- return 1 , nil
456- case ElementDatetime : // Timestamp
457- return 8 , nil
458- case ElementNil : // Nil
459- return 0 , nil
460- case ElementRegEx : // RegEx
461- end := offset
462- for i := 0 ; i < 2 ; i ++ {
463- for end < len (buffer ) && buffer [end ] != '\x00' {
464- end ++
465- }
466- end ++
467- }
468- if end > len (buffer ) {
469- return 0 , io .ErrUnexpectedEOF
470- }
471- return end - offset , nil
472- case ElementDBPointer : // DBPointer
473- size , err := getSize (offset , buffer )
474- if err != nil {
475- return 0 , err
476- }
477- if size < 1 {
478- return 0 , errors .New ("String size can't be less then one byte" )
479- }
480- return size + 12 + 4 , nil
481- case ElementJavaScriptWithScope : // JavaScript with scope
482- size , err := getSize (offset , buffer )
483- if err != nil {
484- return 0 , err
485- }
486- if size < 4 + 5 + 5 {
487- return 0 , errors .New ("Declared document element is too small" )
488- }
489- return size , nil
490- case ElementInt32 : // Int32
491- return 4 , nil
492- case ElementTimestamp : // Mongo-specific timestamp
493- return 8 , nil
494- case ElementInt64 : // Int64
495- return 8 , nil
496- case ElementDecimal128 : // Decimal128
497- return 16 , nil
498- case ElementMaxKey : // Max key
499- return 0 , nil
500- case ElementMinKey : // Min key
501- return 0 , nil
502- default :
503- return 0 , errors .New (fmt .Sprintf ("Unknown element kind (0x%02X)" , byte (kind )))
408+ value , _ , ok := bsoncore .ReadValue (buffer [offset :], kind )
409+ if ! ok {
410+ return 0 , bsoncore .ErrCorruptedDocument
504411 }
412+ return len (value .Data ), nil
505413}
506414
507415func (d * decoder ) readRaw (kind bsontype.Type ) Raw {
0 commit comments