json.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. // Copyright 2016 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package hexutil
  17. import (
  18. "encoding/hex"
  19. "encoding/json"
  20. "fmt"
  21. "math/big"
  22. "reflect"
  23. "strconv"
  24. )
  25. var (
  26. textZero = []byte(`0x0`)
  27. bytesT = reflect.TypeOf(Bytes(nil))
  28. bigT = reflect.TypeOf((*Big)(nil))
  29. uintT = reflect.TypeOf(Uint(0))
  30. uint64T = reflect.TypeOf(Uint64(0))
  31. )
  32. // Bytes marshals/unmarshals as a JSON string with 0x prefix.
  33. // The empty slice marshals as "0x".
  34. type Bytes []byte
  35. // MarshalText implements encoding.TextMarshaler
  36. func (b Bytes) MarshalText() ([]byte, error) {
  37. result := make([]byte, len(b)*2+2)
  38. copy(result, `0x`)
  39. hex.Encode(result[2:], b)
  40. return result, nil
  41. }
  42. // UnmarshalJSON implements json.Unmarshaler.
  43. func (b *Bytes) UnmarshalJSON(input []byte) error {
  44. if !isString(input) {
  45. return errNonString(bytesT)
  46. }
  47. return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT)
  48. }
  49. // UnmarshalText implements encoding.TextUnmarshaler.
  50. func (b *Bytes) UnmarshalText(input []byte) error {
  51. raw, err := checkText(input, true)
  52. if err != nil {
  53. return err
  54. }
  55. dec := make([]byte, len(raw)/2)
  56. if _, err = hex.Decode(dec, raw); err != nil {
  57. err = mapError(err)
  58. } else {
  59. *b = dec
  60. }
  61. return err
  62. }
  63. // String returns the hex encoding of b.
  64. func (b Bytes) String() string {
  65. return Encode(b)
  66. }
  67. // UnmarshalFixedJSON decodes the input as a string with 0x prefix. The length of out
  68. // determines the required input length. This function is commonly used to implement the
  69. // UnmarshalJSON method for fixed-size types.
  70. func UnmarshalFixedJSON(typ reflect.Type, input, out []byte) error {
  71. if !isString(input) {
  72. return errNonString(typ)
  73. }
  74. return wrapTypeError(UnmarshalFixedText(typ.String(), input[1:len(input)-1], out), typ)
  75. }
  76. // UnmarshalFixedText decodes the input as a string with 0x prefix. The length of out
  77. // determines the required input length. This function is commonly used to implement the
  78. // UnmarshalText method for fixed-size types.
  79. func UnmarshalFixedText(typname string, input, out []byte) error {
  80. raw, err := checkText(input, true)
  81. if err != nil {
  82. return err
  83. }
  84. if len(raw)/2 != len(out) {
  85. return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
  86. }
  87. // Pre-verify syntax before modifying out.
  88. for _, b := range raw {
  89. if decodeNibble(b) == badNibble {
  90. return ErrSyntax
  91. }
  92. }
  93. hex.Decode(out, raw)
  94. return nil
  95. }
  96. // UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The
  97. // length of out determines the required input length. This function is commonly used to
  98. // implement the UnmarshalText method for fixed-size types.
  99. func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error {
  100. raw, err := checkText(input, false)
  101. if err != nil {
  102. return err
  103. }
  104. if len(raw)/2 != len(out) {
  105. return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
  106. }
  107. // Pre-verify syntax before modifying out.
  108. for _, b := range raw {
  109. if decodeNibble(b) == badNibble {
  110. return ErrSyntax
  111. }
  112. }
  113. hex.Decode(out, raw)
  114. return nil
  115. }
  116. // Big marshals/unmarshals as a JSON string with 0x prefix.
  117. // The zero value marshals as "0x0".
  118. //
  119. // Negative integers are not supported at this time. Attempting to marshal them will
  120. // return an error. Values larger than 256bits are rejected by Unmarshal but will be
  121. // marshaled without error.
  122. type Big big.Int
  123. // MarshalText implements encoding.TextMarshaler
  124. func (b Big) MarshalText() ([]byte, error) {
  125. return []byte(EncodeBig((*big.Int)(&b))), nil
  126. }
  127. // UnmarshalJSON implements json.Unmarshaler.
  128. func (b *Big) UnmarshalJSON(input []byte) error {
  129. if !isString(input) {
  130. return errNonString(bigT)
  131. }
  132. return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bigT)
  133. }
  134. // UnmarshalText implements encoding.TextUnmarshaler
  135. func (b *Big) UnmarshalText(input []byte) error {
  136. raw, err := checkNumberText(input)
  137. if err != nil {
  138. return err
  139. }
  140. if len(raw) > 64 {
  141. return ErrBig256Range
  142. }
  143. words := make([]big.Word, len(raw)/bigWordNibbles+1)
  144. end := len(raw)
  145. for i := range words {
  146. start := end - bigWordNibbles
  147. if start < 0 {
  148. start = 0
  149. }
  150. for ri := start; ri < end; ri++ {
  151. nib := decodeNibble(raw[ri])
  152. if nib == badNibble {
  153. return ErrSyntax
  154. }
  155. words[i] *= 16
  156. words[i] += big.Word(nib)
  157. }
  158. end = start
  159. }
  160. var dec big.Int
  161. dec.SetBits(words)
  162. *b = (Big)(dec)
  163. return nil
  164. }
  165. // ToInt converts b to a big.Int.
  166. func (b *Big) ToInt() *big.Int {
  167. return (*big.Int)(b)
  168. }
  169. // String returns the hex encoding of b.
  170. func (b *Big) String() string {
  171. return EncodeBig(b.ToInt())
  172. }
  173. // Uint64 marshals/unmarshals as a JSON string with 0x prefix.
  174. // The zero value marshals as "0x0".
  175. type Uint64 uint64
  176. // MarshalText implements encoding.TextMarshaler.
  177. func (b Uint64) MarshalText() ([]byte, error) {
  178. buf := make([]byte, 2, 10)
  179. copy(buf, `0x`)
  180. buf = strconv.AppendUint(buf, uint64(b), 16)
  181. return buf, nil
  182. }
  183. // UnmarshalJSON implements json.Unmarshaler.
  184. func (b *Uint64) UnmarshalJSON(input []byte) error {
  185. if !isString(input) {
  186. return errNonString(uint64T)
  187. }
  188. return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uint64T)
  189. }
  190. // UnmarshalText implements encoding.TextUnmarshaler
  191. func (b *Uint64) UnmarshalText(input []byte) error {
  192. raw, err := checkNumberText(input)
  193. if err != nil {
  194. return err
  195. }
  196. if len(raw) > 16 {
  197. return ErrUint64Range
  198. }
  199. var dec uint64
  200. for _, byte := range raw {
  201. nib := decodeNibble(byte)
  202. if nib == badNibble {
  203. return ErrSyntax
  204. }
  205. dec *= 16
  206. dec += uint64(nib)
  207. }
  208. *b = Uint64(dec)
  209. return nil
  210. }
  211. // String returns the hex encoding of b.
  212. func (b Uint64) String() string {
  213. return EncodeUint64(uint64(b))
  214. }
  215. // Uint marshals/unmarshals as a JSON string with 0x prefix.
  216. // The zero value marshals as "0x0".
  217. type Uint uint
  218. // MarshalText implements encoding.TextMarshaler.
  219. func (b Uint) MarshalText() ([]byte, error) {
  220. return Uint64(b).MarshalText()
  221. }
  222. // UnmarshalJSON implements json.Unmarshaler.
  223. func (b *Uint) UnmarshalJSON(input []byte) error {
  224. if !isString(input) {
  225. return errNonString(uintT)
  226. }
  227. return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uintT)
  228. }
  229. // UnmarshalText implements encoding.TextUnmarshaler.
  230. func (b *Uint) UnmarshalText(input []byte) error {
  231. var u64 Uint64
  232. err := u64.UnmarshalText(input)
  233. if u64 > Uint64(^uint(0)) || err == ErrUint64Range {
  234. return ErrUintRange
  235. } else if err != nil {
  236. return err
  237. }
  238. *b = Uint(u64)
  239. return nil
  240. }
  241. // String returns the hex encoding of b.
  242. func (b Uint) String() string {
  243. return EncodeUint64(uint64(b))
  244. }
  245. func isString(input []byte) bool {
  246. return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"'
  247. }
  248. func bytesHave0xPrefix(input []byte) bool {
  249. return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X')
  250. }
  251. func checkText(input []byte, wantPrefix bool) ([]byte, error) {
  252. if len(input) == 0 {
  253. return nil, nil // empty strings are allowed
  254. }
  255. if bytesHave0xPrefix(input) {
  256. input = input[2:]
  257. } else if wantPrefix {
  258. return nil, ErrMissingPrefix
  259. }
  260. if len(input)%2 != 0 {
  261. return nil, ErrOddLength
  262. }
  263. return input, nil
  264. }
  265. func checkNumberText(input []byte) (raw []byte, err error) {
  266. if len(input) == 0 {
  267. return nil, nil // empty strings are allowed
  268. }
  269. if !bytesHave0xPrefix(input) {
  270. return nil, ErrMissingPrefix
  271. }
  272. input = input[2:]
  273. if len(input) == 0 {
  274. return nil, ErrEmptyNumber
  275. }
  276. if len(input) > 1 && input[0] == '0' {
  277. return nil, ErrLeadingZero
  278. }
  279. return input, nil
  280. }
  281. func wrapTypeError(err error, typ reflect.Type) error {
  282. if _, ok := err.(*decError); ok {
  283. return &json.UnmarshalTypeError{Value: err.Error(), Type: typ}
  284. }
  285. return err
  286. }
  287. func errNonString(typ reflect.Type) error {
  288. return &json.UnmarshalTypeError{Value: "non-string", Type: typ}
  289. }