@@ -166,6 +166,12 @@ func (d *DataDecoder) DecodeBytes(size, offset uint) ([]byte, uint, error) {
166166
167167// DecodeFloat64 decodes a 64-bit float from the given offset.
168168func (d * DataDecoder ) DecodeFloat64 (size , offset uint ) (float64 , uint , error ) {
169+ if size != 8 {
170+ return 0 , 0 , mmdberrors .NewInvalidDatabaseError (
171+ "the MaxMind DB file's data section contains bad data (float 64 size of %v)" ,
172+ size ,
173+ )
174+ }
169175 if offset + size > uint (len (d .buffer )) {
170176 return 0 , 0 , mmdberrors .NewOffsetError ()
171177 }
@@ -177,6 +183,12 @@ func (d *DataDecoder) DecodeFloat64(size, offset uint) (float64, uint, error) {
177183
178184// DecodeFloat32 decodes a 32-bit float from the given offset.
179185func (d * DataDecoder ) DecodeFloat32 (size , offset uint ) (float32 , uint , error ) {
186+ if size != 4 {
187+ return 0 , 0 , mmdberrors .NewInvalidDatabaseError (
188+ "the MaxMind DB file's data section contains bad data (float32 size of %v)" ,
189+ size ,
190+ )
191+ }
180192 if offset + size > uint (len (d .buffer )) {
181193 return 0 , 0 , mmdberrors .NewOffsetError ()
182194 }
@@ -188,6 +200,12 @@ func (d *DataDecoder) DecodeFloat32(size, offset uint) (float32, uint, error) {
188200
189201// DecodeInt32 decodes a 32-bit signed integer from the given offset.
190202func (d * DataDecoder ) DecodeInt32 (size , offset uint ) (int32 , uint , error ) {
203+ if size > 4 {
204+ return 0 , 0 , mmdberrors .NewInvalidDatabaseError (
205+ "the MaxMind DB file's data section contains bad data (int32 size of %v)" ,
206+ size ,
207+ )
208+ }
191209 if offset + size > uint (len (d .buffer )) {
192210 return 0 , 0 , mmdberrors .NewOffsetError ()
193211 }
@@ -236,6 +254,18 @@ func (d *DataDecoder) DecodePointer(
236254 return pointer , newOffset , nil
237255}
238256
257+ // DecodeBool decodes a boolean from the given offset.
258+ func (* DataDecoder ) DecodeBool (size , offset uint ) (bool , uint , error ) {
259+ if size > 1 {
260+ return false , 0 , mmdberrors .NewInvalidDatabaseError (
261+ "the MaxMind DB file's data section contains bad data (bool size of %v)" ,
262+ size ,
263+ )
264+ }
265+ value , newOffset := decodeBool (size , offset )
266+ return value , newOffset , nil
267+ }
268+
239269// DecodeString decodes a string from the given offset.
240270func (d * DataDecoder ) DecodeString (size , offset uint ) (string , uint , error ) {
241271 if offset + size > uint (len (d .buffer )) {
@@ -249,6 +279,12 @@ func (d *DataDecoder) DecodeString(size, offset uint) (string, uint, error) {
249279
250280// DecodeUint16 decodes a 16-bit unsigned integer from the given offset.
251281func (d * DataDecoder ) DecodeUint16 (size , offset uint ) (uint16 , uint , error ) {
282+ if size > 2 {
283+ return 0 , 0 , mmdberrors .NewInvalidDatabaseError (
284+ "the MaxMind DB file's data section contains bad data (uint16 size of %v)" ,
285+ size ,
286+ )
287+ }
252288 if offset + size > uint (len (d .buffer )) {
253289 return 0 , 0 , mmdberrors .NewOffsetError ()
254290 }
@@ -265,6 +301,12 @@ func (d *DataDecoder) DecodeUint16(size, offset uint) (uint16, uint, error) {
265301
266302// DecodeUint32 decodes a 32-bit unsigned integer from the given offset.
267303func (d * DataDecoder ) DecodeUint32 (size , offset uint ) (uint32 , uint , error ) {
304+ if size > 4 {
305+ return 0 , 0 , mmdberrors .NewInvalidDatabaseError (
306+ "the MaxMind DB file's data section contains bad data (uint32 size of %v)" ,
307+ size ,
308+ )
309+ }
268310 if offset + size > uint (len (d .buffer )) {
269311 return 0 , 0 , mmdberrors .NewOffsetError ()
270312 }
@@ -281,6 +323,12 @@ func (d *DataDecoder) DecodeUint32(size, offset uint) (uint32, uint, error) {
281323
282324// DecodeUint64 decodes a 64-bit unsigned integer from the given offset.
283325func (d * DataDecoder ) DecodeUint64 (size , offset uint ) (uint64 , uint , error ) {
326+ if size > 8 {
327+ return 0 , 0 , mmdberrors .NewInvalidDatabaseError (
328+ "the MaxMind DB file's data section contains bad data (uint64 size of %v)" ,
329+ size ,
330+ )
331+ }
284332 if offset + size > uint (len (d .buffer )) {
285333 return 0 , 0 , mmdberrors .NewOffsetError ()
286334 }
@@ -296,16 +344,32 @@ func (d *DataDecoder) DecodeUint64(size, offset uint) (uint64, uint, error) {
296344}
297345
298346// DecodeUint128 decodes a 128-bit unsigned integer from the given offset.
299- func (d * DataDecoder ) DecodeUint128 (size , offset uint ) (* big.Int , uint , error ) {
347+ // Returns the value as high and low 64-bit unsigned integers.
348+ func (d * DataDecoder ) DecodeUint128 (size , offset uint ) (hi , lo uint64 , newOffset uint , err error ) {
349+ if size > 16 {
350+ return 0 , 0 , 0 , mmdberrors .NewInvalidDatabaseError (
351+ "the MaxMind DB file's data section contains bad data (uint128 size of %v)" ,
352+ size ,
353+ )
354+ }
300355 if offset + size > uint (len (d .buffer )) {
301- return nil , 0 , mmdberrors .NewOffsetError ()
356+ return 0 , 0 , 0 , mmdberrors .NewOffsetError ()
302357 }
303358
304- newOffset := offset + size
305- val := new (big.Int )
306- val .SetBytes (d .buffer [offset :newOffset ])
359+ newOffset = offset + size
307360
308- return val , newOffset , nil
361+ // Process bytes from most significant to least significant
362+ for _ , b := range d .buffer [offset :newOffset ] {
363+ var carry byte
364+ lo , carry = append64 (lo , b )
365+ hi , _ = append64 (hi , carry )
366+ }
367+
368+ return hi , lo , newOffset , nil
369+ }
370+
371+ func append64 (val uint64 , b byte ) (uint64 , byte ) {
372+ return (val << 8 ) | uint64 (b ), byte (val >> 56 )
309373}
310374
311375// DecodeKey decodes a map key into []byte slice. We use a []byte so that we
@@ -509,12 +573,22 @@ func (d *DataDecoder) decodeFromTypeToDeserializer(
509573
510574 return offset , dser .Uint64 (v )
511575 case KindUint128 :
512- v , offset , err := d .DecodeUint128 (size , offset )
576+ hi , lo , offset , err := d .DecodeUint128 (size , offset )
513577 if err != nil {
514578 return 0 , err
515579 }
516580
517- return offset , dser .Uint128 (v )
581+ // Convert hi/lo representation to big.Int for deserializer
582+ value := new (big.Int )
583+ if hi == 0 {
584+ value .SetUint64 (lo )
585+ } else {
586+ value .SetUint64 (hi )
587+ value .Lsh (value , 64 ) // Shift high part left by 64 bits
588+ value .Or (value , new (big.Int ).SetUint64 (lo )) // OR with low part
589+ }
590+
591+ return offset , dser .Uint128 (value )
518592 default :
519593 return 0 , mmdberrors .NewInvalidDatabaseError ("unknown type: %d" , dtype )
520594 }
0 commit comments