decoder.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. package maxminddb
  2. import (
  3. "encoding/binary"
  4. "math"
  5. "math/big"
  6. "reflect"
  7. "sync"
  8. )
  9. type decoder struct {
  10. buffer []byte
  11. }
  12. type dataType int
  13. const (
  14. _Extended dataType = iota
  15. _Pointer
  16. _String
  17. _Float64
  18. _Bytes
  19. _Uint16
  20. _Uint32
  21. _Map
  22. _Int32
  23. _Uint64
  24. _Uint128
  25. _Slice
  26. // We don't use the next two. They are placeholders. See the spec
  27. // for more details.
  28. _Container //nolint: deadcode, varcheck // above
  29. _Marker //nolint: deadcode, varcheck // above
  30. _Bool
  31. _Float32
  32. )
  33. const (
  34. // This is the value used in libmaxminddb.
  35. maximumDataStructureDepth = 512
  36. )
  37. func (d *decoder) decode(offset uint, result reflect.Value, depth int) (uint, error) {
  38. if depth > maximumDataStructureDepth {
  39. return 0, newInvalidDatabaseError(
  40. "exceeded maximum data structure depth; database is likely corrupt",
  41. )
  42. }
  43. typeNum, size, newOffset, err := d.decodeCtrlData(offset)
  44. if err != nil {
  45. return 0, err
  46. }
  47. if typeNum != _Pointer && result.Kind() == reflect.Uintptr {
  48. result.Set(reflect.ValueOf(uintptr(offset)))
  49. return d.nextValueOffset(offset, 1)
  50. }
  51. return d.decodeFromType(typeNum, size, newOffset, result, depth+1)
  52. }
  53. func (d *decoder) decodeToDeserializer(
  54. offset uint,
  55. dser deserializer,
  56. depth int,
  57. getNext bool,
  58. ) (uint, error) {
  59. if depth > maximumDataStructureDepth {
  60. return 0, newInvalidDatabaseError(
  61. "exceeded maximum data structure depth; database is likely corrupt",
  62. )
  63. }
  64. skip, err := dser.ShouldSkip(uintptr(offset))
  65. if err != nil {
  66. return 0, err
  67. }
  68. if skip {
  69. if getNext {
  70. return d.nextValueOffset(offset, 1)
  71. }
  72. return 0, nil
  73. }
  74. typeNum, size, newOffset, err := d.decodeCtrlData(offset)
  75. if err != nil {
  76. return 0, err
  77. }
  78. return d.decodeFromTypeToDeserializer(typeNum, size, newOffset, dser, depth+1)
  79. }
  80. func (d *decoder) decodeCtrlData(offset uint) (dataType, uint, uint, error) {
  81. newOffset := offset + 1
  82. if offset >= uint(len(d.buffer)) {
  83. return 0, 0, 0, newOffsetError()
  84. }
  85. ctrlByte := d.buffer[offset]
  86. typeNum := dataType(ctrlByte >> 5)
  87. if typeNum == _Extended {
  88. if newOffset >= uint(len(d.buffer)) {
  89. return 0, 0, 0, newOffsetError()
  90. }
  91. typeNum = dataType(d.buffer[newOffset] + 7)
  92. newOffset++
  93. }
  94. var size uint
  95. size, newOffset, err := d.sizeFromCtrlByte(ctrlByte, newOffset, typeNum)
  96. return typeNum, size, newOffset, err
  97. }
  98. func (d *decoder) sizeFromCtrlByte(
  99. ctrlByte byte,
  100. offset uint,
  101. typeNum dataType,
  102. ) (uint, uint, error) {
  103. size := uint(ctrlByte & 0x1f)
  104. if typeNum == _Extended {
  105. return size, offset, nil
  106. }
  107. var bytesToRead uint
  108. if size < 29 {
  109. return size, offset, nil
  110. }
  111. bytesToRead = size - 28
  112. newOffset := offset + bytesToRead
  113. if newOffset > uint(len(d.buffer)) {
  114. return 0, 0, newOffsetError()
  115. }
  116. if size == 29 {
  117. return 29 + uint(d.buffer[offset]), offset + 1, nil
  118. }
  119. sizeBytes := d.buffer[offset:newOffset]
  120. switch {
  121. case size == 30:
  122. size = 285 + uintFromBytes(0, sizeBytes)
  123. case size > 30:
  124. size = uintFromBytes(0, sizeBytes) + 65821
  125. }
  126. return size, newOffset, nil
  127. }
  128. func (d *decoder) decodeFromType(
  129. dtype dataType,
  130. size uint,
  131. offset uint,
  132. result reflect.Value,
  133. depth int,
  134. ) (uint, error) {
  135. result = indirect(result)
  136. // For these types, size has a special meaning
  137. switch dtype {
  138. case _Bool:
  139. return unmarshalBool(size, offset, result)
  140. case _Map:
  141. return d.unmarshalMap(size, offset, result, depth)
  142. case _Pointer:
  143. return d.unmarshalPointer(size, offset, result, depth)
  144. case _Slice:
  145. return d.unmarshalSlice(size, offset, result, depth)
  146. }
  147. // For the remaining types, size is the byte size
  148. if offset+size > uint(len(d.buffer)) {
  149. return 0, newOffsetError()
  150. }
  151. switch dtype {
  152. case _Bytes:
  153. return d.unmarshalBytes(size, offset, result)
  154. case _Float32:
  155. return d.unmarshalFloat32(size, offset, result)
  156. case _Float64:
  157. return d.unmarshalFloat64(size, offset, result)
  158. case _Int32:
  159. return d.unmarshalInt32(size, offset, result)
  160. case _String:
  161. return d.unmarshalString(size, offset, result)
  162. case _Uint16:
  163. return d.unmarshalUint(size, offset, result, 16)
  164. case _Uint32:
  165. return d.unmarshalUint(size, offset, result, 32)
  166. case _Uint64:
  167. return d.unmarshalUint(size, offset, result, 64)
  168. case _Uint128:
  169. return d.unmarshalUint128(size, offset, result)
  170. default:
  171. return 0, newInvalidDatabaseError("unknown type: %d", dtype)
  172. }
  173. }
  174. func (d *decoder) decodeFromTypeToDeserializer(
  175. dtype dataType,
  176. size uint,
  177. offset uint,
  178. dser deserializer,
  179. depth int,
  180. ) (uint, error) {
  181. // For these types, size has a special meaning
  182. switch dtype {
  183. case _Bool:
  184. v, offset := decodeBool(size, offset)
  185. return offset, dser.Bool(v)
  186. case _Map:
  187. return d.decodeMapToDeserializer(size, offset, dser, depth)
  188. case _Pointer:
  189. pointer, newOffset, err := d.decodePointer(size, offset)
  190. if err != nil {
  191. return 0, err
  192. }
  193. _, err = d.decodeToDeserializer(pointer, dser, depth, false)
  194. return newOffset, err
  195. case _Slice:
  196. return d.decodeSliceToDeserializer(size, offset, dser, depth)
  197. }
  198. // For the remaining types, size is the byte size
  199. if offset+size > uint(len(d.buffer)) {
  200. return 0, newOffsetError()
  201. }
  202. switch dtype {
  203. case _Bytes:
  204. v, offset := d.decodeBytes(size, offset)
  205. return offset, dser.Bytes(v)
  206. case _Float32:
  207. v, offset := d.decodeFloat32(size, offset)
  208. return offset, dser.Float32(v)
  209. case _Float64:
  210. v, offset := d.decodeFloat64(size, offset)
  211. return offset, dser.Float64(v)
  212. case _Int32:
  213. v, offset := d.decodeInt(size, offset)
  214. return offset, dser.Int32(int32(v))
  215. case _String:
  216. v, offset := d.decodeString(size, offset)
  217. return offset, dser.String(v)
  218. case _Uint16:
  219. v, offset := d.decodeUint(size, offset)
  220. return offset, dser.Uint16(uint16(v))
  221. case _Uint32:
  222. v, offset := d.decodeUint(size, offset)
  223. return offset, dser.Uint32(uint32(v))
  224. case _Uint64:
  225. v, offset := d.decodeUint(size, offset)
  226. return offset, dser.Uint64(v)
  227. case _Uint128:
  228. v, offset := d.decodeUint128(size, offset)
  229. return offset, dser.Uint128(v)
  230. default:
  231. return 0, newInvalidDatabaseError("unknown type: %d", dtype)
  232. }
  233. }
  234. func unmarshalBool(size, offset uint, result reflect.Value) (uint, error) {
  235. if size > 1 {
  236. return 0, newInvalidDatabaseError(
  237. "the MaxMind DB file's data section contains bad data (bool size of %v)",
  238. size,
  239. )
  240. }
  241. value, newOffset := decodeBool(size, offset)
  242. switch result.Kind() {
  243. case reflect.Bool:
  244. result.SetBool(value)
  245. return newOffset, nil
  246. case reflect.Interface:
  247. if result.NumMethod() == 0 {
  248. result.Set(reflect.ValueOf(value))
  249. return newOffset, nil
  250. }
  251. }
  252. return newOffset, newUnmarshalTypeError(value, result.Type())
  253. }
  254. // indirect follows pointers and create values as necessary. This is
  255. // heavily based on encoding/json as my original version had a subtle
  256. // bug. This method should be considered to be licensed under
  257. // https://golang.org/LICENSE
  258. func indirect(result reflect.Value) reflect.Value {
  259. for {
  260. // Load value from interface, but only if the result will be
  261. // usefully addressable.
  262. if result.Kind() == reflect.Interface && !result.IsNil() {
  263. e := result.Elem()
  264. if e.Kind() == reflect.Ptr && !e.IsNil() {
  265. result = e
  266. continue
  267. }
  268. }
  269. if result.Kind() != reflect.Ptr {
  270. break
  271. }
  272. if result.IsNil() {
  273. result.Set(reflect.New(result.Type().Elem()))
  274. }
  275. result = result.Elem()
  276. }
  277. return result
  278. }
  279. var sliceType = reflect.TypeOf([]byte{})
  280. func (d *decoder) unmarshalBytes(size, offset uint, result reflect.Value) (uint, error) {
  281. value, newOffset := d.decodeBytes(size, offset)
  282. switch result.Kind() {
  283. case reflect.Slice:
  284. if result.Type() == sliceType {
  285. result.SetBytes(value)
  286. return newOffset, nil
  287. }
  288. case reflect.Interface:
  289. if result.NumMethod() == 0 {
  290. result.Set(reflect.ValueOf(value))
  291. return newOffset, nil
  292. }
  293. }
  294. return newOffset, newUnmarshalTypeError(value, result.Type())
  295. }
  296. func (d *decoder) unmarshalFloat32(size, offset uint, result reflect.Value) (uint, error) {
  297. if size != 4 {
  298. return 0, newInvalidDatabaseError(
  299. "the MaxMind DB file's data section contains bad data (float32 size of %v)",
  300. size,
  301. )
  302. }
  303. value, newOffset := d.decodeFloat32(size, offset)
  304. switch result.Kind() {
  305. case reflect.Float32, reflect.Float64:
  306. result.SetFloat(float64(value))
  307. return newOffset, nil
  308. case reflect.Interface:
  309. if result.NumMethod() == 0 {
  310. result.Set(reflect.ValueOf(value))
  311. return newOffset, nil
  312. }
  313. }
  314. return newOffset, newUnmarshalTypeError(value, result.Type())
  315. }
  316. func (d *decoder) unmarshalFloat64(size, offset uint, result reflect.Value) (uint, error) {
  317. if size != 8 {
  318. return 0, newInvalidDatabaseError(
  319. "the MaxMind DB file's data section contains bad data (float 64 size of %v)",
  320. size,
  321. )
  322. }
  323. value, newOffset := d.decodeFloat64(size, offset)
  324. switch result.Kind() {
  325. case reflect.Float32, reflect.Float64:
  326. if result.OverflowFloat(value) {
  327. return 0, newUnmarshalTypeError(value, result.Type())
  328. }
  329. result.SetFloat(value)
  330. return newOffset, nil
  331. case reflect.Interface:
  332. if result.NumMethod() == 0 {
  333. result.Set(reflect.ValueOf(value))
  334. return newOffset, nil
  335. }
  336. }
  337. return newOffset, newUnmarshalTypeError(value, result.Type())
  338. }
  339. func (d *decoder) unmarshalInt32(size, offset uint, result reflect.Value) (uint, error) {
  340. if size > 4 {
  341. return 0, newInvalidDatabaseError(
  342. "the MaxMind DB file's data section contains bad data (int32 size of %v)",
  343. size,
  344. )
  345. }
  346. value, newOffset := d.decodeInt(size, offset)
  347. switch result.Kind() {
  348. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  349. n := int64(value)
  350. if !result.OverflowInt(n) {
  351. result.SetInt(n)
  352. return newOffset, nil
  353. }
  354. case reflect.Uint,
  355. reflect.Uint8,
  356. reflect.Uint16,
  357. reflect.Uint32,
  358. reflect.Uint64,
  359. reflect.Uintptr:
  360. n := uint64(value)
  361. if !result.OverflowUint(n) {
  362. result.SetUint(n)
  363. return newOffset, nil
  364. }
  365. case reflect.Interface:
  366. if result.NumMethod() == 0 {
  367. result.Set(reflect.ValueOf(value))
  368. return newOffset, nil
  369. }
  370. }
  371. return newOffset, newUnmarshalTypeError(value, result.Type())
  372. }
  373. func (d *decoder) unmarshalMap(
  374. size uint,
  375. offset uint,
  376. result reflect.Value,
  377. depth int,
  378. ) (uint, error) {
  379. result = indirect(result)
  380. switch result.Kind() {
  381. default:
  382. return 0, newUnmarshalTypeError("map", result.Type())
  383. case reflect.Struct:
  384. return d.decodeStruct(size, offset, result, depth)
  385. case reflect.Map:
  386. return d.decodeMap(size, offset, result, depth)
  387. case reflect.Interface:
  388. if result.NumMethod() == 0 {
  389. rv := reflect.ValueOf(make(map[string]any, size))
  390. newOffset, err := d.decodeMap(size, offset, rv, depth)
  391. result.Set(rv)
  392. return newOffset, err
  393. }
  394. return 0, newUnmarshalTypeError("map", result.Type())
  395. }
  396. }
  397. func (d *decoder) unmarshalPointer(
  398. size, offset uint,
  399. result reflect.Value,
  400. depth int,
  401. ) (uint, error) {
  402. pointer, newOffset, err := d.decodePointer(size, offset)
  403. if err != nil {
  404. return 0, err
  405. }
  406. _, err = d.decode(pointer, result, depth)
  407. return newOffset, err
  408. }
  409. func (d *decoder) unmarshalSlice(
  410. size uint,
  411. offset uint,
  412. result reflect.Value,
  413. depth int,
  414. ) (uint, error) {
  415. switch result.Kind() {
  416. case reflect.Slice:
  417. return d.decodeSlice(size, offset, result, depth)
  418. case reflect.Interface:
  419. if result.NumMethod() == 0 {
  420. a := []any{}
  421. rv := reflect.ValueOf(&a).Elem()
  422. newOffset, err := d.decodeSlice(size, offset, rv, depth)
  423. result.Set(rv)
  424. return newOffset, err
  425. }
  426. }
  427. return 0, newUnmarshalTypeError("array", result.Type())
  428. }
  429. func (d *decoder) unmarshalString(size, offset uint, result reflect.Value) (uint, error) {
  430. value, newOffset := d.decodeString(size, offset)
  431. switch result.Kind() {
  432. case reflect.String:
  433. result.SetString(value)
  434. return newOffset, nil
  435. case reflect.Interface:
  436. if result.NumMethod() == 0 {
  437. result.Set(reflect.ValueOf(value))
  438. return newOffset, nil
  439. }
  440. }
  441. return newOffset, newUnmarshalTypeError(value, result.Type())
  442. }
  443. func (d *decoder) unmarshalUint(
  444. size, offset uint,
  445. result reflect.Value,
  446. uintType uint,
  447. ) (uint, error) {
  448. if size > uintType/8 {
  449. return 0, newInvalidDatabaseError(
  450. "the MaxMind DB file's data section contains bad data (uint%v size of %v)",
  451. uintType,
  452. size,
  453. )
  454. }
  455. value, newOffset := d.decodeUint(size, offset)
  456. switch result.Kind() {
  457. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  458. n := int64(value)
  459. if !result.OverflowInt(n) {
  460. result.SetInt(n)
  461. return newOffset, nil
  462. }
  463. case reflect.Uint,
  464. reflect.Uint8,
  465. reflect.Uint16,
  466. reflect.Uint32,
  467. reflect.Uint64,
  468. reflect.Uintptr:
  469. if !result.OverflowUint(value) {
  470. result.SetUint(value)
  471. return newOffset, nil
  472. }
  473. case reflect.Interface:
  474. if result.NumMethod() == 0 {
  475. result.Set(reflect.ValueOf(value))
  476. return newOffset, nil
  477. }
  478. }
  479. return newOffset, newUnmarshalTypeError(value, result.Type())
  480. }
  481. var bigIntType = reflect.TypeOf(big.Int{})
  482. func (d *decoder) unmarshalUint128(size, offset uint, result reflect.Value) (uint, error) {
  483. if size > 16 {
  484. return 0, newInvalidDatabaseError(
  485. "the MaxMind DB file's data section contains bad data (uint128 size of %v)",
  486. size,
  487. )
  488. }
  489. value, newOffset := d.decodeUint128(size, offset)
  490. switch result.Kind() {
  491. case reflect.Struct:
  492. if result.Type() == bigIntType {
  493. result.Set(reflect.ValueOf(*value))
  494. return newOffset, nil
  495. }
  496. case reflect.Interface:
  497. if result.NumMethod() == 0 {
  498. result.Set(reflect.ValueOf(value))
  499. return newOffset, nil
  500. }
  501. }
  502. return newOffset, newUnmarshalTypeError(value, result.Type())
  503. }
  504. func decodeBool(size, offset uint) (bool, uint) {
  505. return size != 0, offset
  506. }
  507. func (d *decoder) decodeBytes(size, offset uint) ([]byte, uint) {
  508. newOffset := offset + size
  509. bytes := make([]byte, size)
  510. copy(bytes, d.buffer[offset:newOffset])
  511. return bytes, newOffset
  512. }
  513. func (d *decoder) decodeFloat64(size, offset uint) (float64, uint) {
  514. newOffset := offset + size
  515. bits := binary.BigEndian.Uint64(d.buffer[offset:newOffset])
  516. return math.Float64frombits(bits), newOffset
  517. }
  518. func (d *decoder) decodeFloat32(size, offset uint) (float32, uint) {
  519. newOffset := offset + size
  520. bits := binary.BigEndian.Uint32(d.buffer[offset:newOffset])
  521. return math.Float32frombits(bits), newOffset
  522. }
  523. func (d *decoder) decodeInt(size, offset uint) (int, uint) {
  524. newOffset := offset + size
  525. var val int32
  526. for _, b := range d.buffer[offset:newOffset] {
  527. val = (val << 8) | int32(b)
  528. }
  529. return int(val), newOffset
  530. }
  531. func (d *decoder) decodeMap(
  532. size uint,
  533. offset uint,
  534. result reflect.Value,
  535. depth int,
  536. ) (uint, error) {
  537. if result.IsNil() {
  538. result.Set(reflect.MakeMapWithSize(result.Type(), int(size)))
  539. }
  540. mapType := result.Type()
  541. keyValue := reflect.New(mapType.Key()).Elem()
  542. elemType := mapType.Elem()
  543. var elemValue reflect.Value
  544. for i := uint(0); i < size; i++ {
  545. var key []byte
  546. var err error
  547. key, offset, err = d.decodeKey(offset)
  548. if err != nil {
  549. return 0, err
  550. }
  551. if elemValue.IsValid() {
  552. // After 1.20 is the minimum supported version, this can just be
  553. // elemValue.SetZero()
  554. reflectSetZero(elemValue)
  555. } else {
  556. elemValue = reflect.New(elemType).Elem()
  557. }
  558. offset, err = d.decode(offset, elemValue, depth)
  559. if err != nil {
  560. return 0, err
  561. }
  562. keyValue.SetString(string(key))
  563. result.SetMapIndex(keyValue, elemValue)
  564. }
  565. return offset, nil
  566. }
  567. func (d *decoder) decodeMapToDeserializer(
  568. size uint,
  569. offset uint,
  570. dser deserializer,
  571. depth int,
  572. ) (uint, error) {
  573. err := dser.StartMap(size)
  574. if err != nil {
  575. return 0, err
  576. }
  577. for i := uint(0); i < size; i++ {
  578. // TODO - implement key/value skipping?
  579. offset, err = d.decodeToDeserializer(offset, dser, depth, true)
  580. if err != nil {
  581. return 0, err
  582. }
  583. offset, err = d.decodeToDeserializer(offset, dser, depth, true)
  584. if err != nil {
  585. return 0, err
  586. }
  587. }
  588. err = dser.End()
  589. if err != nil {
  590. return 0, err
  591. }
  592. return offset, nil
  593. }
  594. func (d *decoder) decodePointer(
  595. size uint,
  596. offset uint,
  597. ) (uint, uint, error) {
  598. pointerSize := ((size >> 3) & 0x3) + 1
  599. newOffset := offset + pointerSize
  600. if newOffset > uint(len(d.buffer)) {
  601. return 0, 0, newOffsetError()
  602. }
  603. pointerBytes := d.buffer[offset:newOffset]
  604. var prefix uint
  605. if pointerSize == 4 {
  606. prefix = 0
  607. } else {
  608. prefix = size & 0x7
  609. }
  610. unpacked := uintFromBytes(prefix, pointerBytes)
  611. var pointerValueOffset uint
  612. switch pointerSize {
  613. case 1:
  614. pointerValueOffset = 0
  615. case 2:
  616. pointerValueOffset = 2048
  617. case 3:
  618. pointerValueOffset = 526336
  619. case 4:
  620. pointerValueOffset = 0
  621. }
  622. pointer := unpacked + pointerValueOffset
  623. return pointer, newOffset, nil
  624. }
  625. func (d *decoder) decodeSlice(
  626. size uint,
  627. offset uint,
  628. result reflect.Value,
  629. depth int,
  630. ) (uint, error) {
  631. result.Set(reflect.MakeSlice(result.Type(), int(size), int(size)))
  632. for i := 0; i < int(size); i++ {
  633. var err error
  634. offset, err = d.decode(offset, result.Index(i), depth)
  635. if err != nil {
  636. return 0, err
  637. }
  638. }
  639. return offset, nil
  640. }
  641. func (d *decoder) decodeSliceToDeserializer(
  642. size uint,
  643. offset uint,
  644. dser deserializer,
  645. depth int,
  646. ) (uint, error) {
  647. err := dser.StartSlice(size)
  648. if err != nil {
  649. return 0, err
  650. }
  651. for i := uint(0); i < size; i++ {
  652. offset, err = d.decodeToDeserializer(offset, dser, depth, true)
  653. if err != nil {
  654. return 0, err
  655. }
  656. }
  657. err = dser.End()
  658. if err != nil {
  659. return 0, err
  660. }
  661. return offset, nil
  662. }
  663. func (d *decoder) decodeString(size, offset uint) (string, uint) {
  664. newOffset := offset + size
  665. return string(d.buffer[offset:newOffset]), newOffset
  666. }
  667. func (d *decoder) decodeStruct(
  668. size uint,
  669. offset uint,
  670. result reflect.Value,
  671. depth int,
  672. ) (uint, error) {
  673. fields := cachedFields(result)
  674. // This fills in embedded structs
  675. for _, i := range fields.anonymousFields {
  676. _, err := d.unmarshalMap(size, offset, result.Field(i), depth)
  677. if err != nil {
  678. return 0, err
  679. }
  680. }
  681. // This handles named fields
  682. for i := uint(0); i < size; i++ {
  683. var (
  684. err error
  685. key []byte
  686. )
  687. key, offset, err = d.decodeKey(offset)
  688. if err != nil {
  689. return 0, err
  690. }
  691. // The string() does not create a copy due to this compiler
  692. // optimization: https://github.com/golang/go/issues/3512
  693. j, ok := fields.namedFields[string(key)]
  694. if !ok {
  695. offset, err = d.nextValueOffset(offset, 1)
  696. if err != nil {
  697. return 0, err
  698. }
  699. continue
  700. }
  701. offset, err = d.decode(offset, result.Field(j), depth)
  702. if err != nil {
  703. return 0, err
  704. }
  705. }
  706. return offset, nil
  707. }
  708. type fieldsType struct {
  709. namedFields map[string]int
  710. anonymousFields []int
  711. }
  712. var fieldsMap sync.Map
  713. func cachedFields(result reflect.Value) *fieldsType {
  714. resultType := result.Type()
  715. if fields, ok := fieldsMap.Load(resultType); ok {
  716. return fields.(*fieldsType)
  717. }
  718. numFields := resultType.NumField()
  719. namedFields := make(map[string]int, numFields)
  720. var anonymous []int
  721. for i := 0; i < numFields; i++ {
  722. field := resultType.Field(i)
  723. fieldName := field.Name
  724. if tag := field.Tag.Get("maxminddb"); tag != "" {
  725. if tag == "-" {
  726. continue
  727. }
  728. fieldName = tag
  729. }
  730. if field.Anonymous {
  731. anonymous = append(anonymous, i)
  732. continue
  733. }
  734. namedFields[fieldName] = i
  735. }
  736. fields := &fieldsType{namedFields, anonymous}
  737. fieldsMap.Store(resultType, fields)
  738. return fields
  739. }
  740. func (d *decoder) decodeUint(size, offset uint) (uint64, uint) {
  741. newOffset := offset + size
  742. bytes := d.buffer[offset:newOffset]
  743. var val uint64
  744. for _, b := range bytes {
  745. val = (val << 8) | uint64(b)
  746. }
  747. return val, newOffset
  748. }
  749. func (d *decoder) decodeUint128(size, offset uint) (*big.Int, uint) {
  750. newOffset := offset + size
  751. val := new(big.Int)
  752. val.SetBytes(d.buffer[offset:newOffset])
  753. return val, newOffset
  754. }
  755. func uintFromBytes(prefix uint, uintBytes []byte) uint {
  756. val := prefix
  757. for _, b := range uintBytes {
  758. val = (val << 8) | uint(b)
  759. }
  760. return val
  761. }
  762. // decodeKey decodes a map key into []byte slice. We use a []byte so that we
  763. // can take advantage of https://github.com/golang/go/issues/3512 to avoid
  764. // copying the bytes when decoding a struct. Previously, we achieved this by
  765. // using unsafe.
  766. func (d *decoder) decodeKey(offset uint) ([]byte, uint, error) {
  767. typeNum, size, dataOffset, err := d.decodeCtrlData(offset)
  768. if err != nil {
  769. return nil, 0, err
  770. }
  771. if typeNum == _Pointer {
  772. pointer, ptrOffset, err := d.decodePointer(size, dataOffset)
  773. if err != nil {
  774. return nil, 0, err
  775. }
  776. key, _, err := d.decodeKey(pointer)
  777. return key, ptrOffset, err
  778. }
  779. if typeNum != _String {
  780. return nil, 0, newInvalidDatabaseError("unexpected type when decoding string: %v", typeNum)
  781. }
  782. newOffset := dataOffset + size
  783. if newOffset > uint(len(d.buffer)) {
  784. return nil, 0, newOffsetError()
  785. }
  786. return d.buffer[dataOffset:newOffset], newOffset, nil
  787. }
  788. // This function is used to skip ahead to the next value without decoding
  789. // the one at the offset passed in. The size bits have different meanings for
  790. // different data types.
  791. func (d *decoder) nextValueOffset(offset, numberToSkip uint) (uint, error) {
  792. if numberToSkip == 0 {
  793. return offset, nil
  794. }
  795. typeNum, size, offset, err := d.decodeCtrlData(offset)
  796. if err != nil {
  797. return 0, err
  798. }
  799. switch typeNum {
  800. case _Pointer:
  801. _, offset, err = d.decodePointer(size, offset)
  802. if err != nil {
  803. return 0, err
  804. }
  805. case _Map:
  806. numberToSkip += 2 * size
  807. case _Slice:
  808. numberToSkip += size
  809. case _Bool:
  810. default:
  811. offset += size
  812. }
  813. return d.nextValueOffset(offset, numberToSkip-1)
  814. }