decoder.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. package binary
  2. import (
  3. "fmt"
  4. "github.com/Rhymen/go-whatsapp/binary/token"
  5. "io"
  6. "strconv"
  7. )
  8. type binaryDecoder struct {
  9. data []byte
  10. index int
  11. }
  12. func NewDecoder(data []byte) *binaryDecoder {
  13. return &binaryDecoder{data, 0}
  14. }
  15. func (r *binaryDecoder) checkEOS(length int) error {
  16. if r.index+length > len(r.data) {
  17. return io.EOF
  18. }
  19. return nil
  20. }
  21. func (r *binaryDecoder) readByte() (byte, error) {
  22. if err := r.checkEOS(1); err != nil {
  23. return 0, err
  24. }
  25. b := r.data[r.index]
  26. r.index++
  27. return b, nil
  28. }
  29. func (r *binaryDecoder) readIntN(n int, littleEndian bool) (int, error) {
  30. if err := r.checkEOS(n); err != nil {
  31. return 0, err
  32. }
  33. var ret int
  34. for i := 0; i < n; i++ {
  35. var curShift int
  36. if littleEndian {
  37. curShift = i
  38. } else {
  39. curShift = n - i - 1
  40. }
  41. ret |= int(r.data[r.index+i]) << uint(curShift*8)
  42. }
  43. r.index += n
  44. return ret, nil
  45. }
  46. func (r *binaryDecoder) readInt8(littleEndian bool) (int, error) {
  47. return r.readIntN(1, littleEndian)
  48. }
  49. func (r *binaryDecoder) readInt16(littleEndian bool) (int, error) {
  50. return r.readIntN(2, littleEndian)
  51. }
  52. func (r *binaryDecoder) readInt20() (int, error) {
  53. if err := r.checkEOS(3); err != nil {
  54. return 0, err
  55. }
  56. ret := ((int(r.data[r.index]) & 15) << 16) + (int(r.data[r.index+1]) << 8) + int(r.data[r.index+2])
  57. r.index += 3
  58. return ret, nil
  59. }
  60. func (r *binaryDecoder) readInt32(littleEndian bool) (int, error) {
  61. return r.readIntN(4, littleEndian)
  62. }
  63. func (r *binaryDecoder) readInt64(littleEndian bool) (int, error) {
  64. return r.readIntN(8, littleEndian)
  65. }
  66. func (r *binaryDecoder) readPacked8(tag int) (string, error) {
  67. startByte, err := r.readByte()
  68. if err != nil {
  69. return "", err
  70. }
  71. ret := ""
  72. for i := 0; i < int(startByte&127); i++ {
  73. currByte, err := r.readByte()
  74. if err != nil {
  75. return "", err
  76. }
  77. lower, err := unpackByte(tag, currByte&0xF0>>4)
  78. if err != nil {
  79. return "", err
  80. }
  81. upper, err := unpackByte(tag, currByte&0x0F)
  82. if err != nil {
  83. return "", err
  84. }
  85. ret += lower + upper
  86. }
  87. if startByte>>7 != 0 {
  88. ret = ret[:len(ret)-1]
  89. }
  90. return ret, nil
  91. }
  92. func unpackByte(tag int, value byte) (string, error) {
  93. switch tag {
  94. case token.NIBBLE_8:
  95. return unpackNibble(value)
  96. case token.HEX_8:
  97. return unpackHex(value)
  98. default:
  99. return "", fmt.Errorf("unpackByte with unknown tag %d", tag)
  100. }
  101. }
  102. func unpackNibble(value byte) (string, error) {
  103. switch {
  104. case value < 0 || value > 15:
  105. return "", fmt.Errorf("unpackNibble with value %d", value)
  106. case value == 10:
  107. return "-", nil
  108. case value == 11:
  109. return ".", nil
  110. case value == 15:
  111. return "\x00", nil
  112. default:
  113. return strconv.Itoa(int(value)), nil
  114. }
  115. }
  116. func unpackHex(value byte) (string, error) {
  117. switch {
  118. case value < 0 || value > 15:
  119. return "", fmt.Errorf("unpackHex with value %d", value)
  120. case value < 10:
  121. return strconv.Itoa(int(value)), nil
  122. default:
  123. return string('A' + value - 10), nil
  124. }
  125. }
  126. func (r *binaryDecoder) readListSize(tag int) (int, error) {
  127. switch tag {
  128. case token.LIST_EMPTY:
  129. return 0, nil
  130. case token.LIST_8:
  131. return r.readInt8(false)
  132. case token.LIST_16:
  133. return r.readInt16(false)
  134. default:
  135. return 0, fmt.Errorf("readListSize with unknown tag %d at position %d", tag, r.index)
  136. }
  137. }
  138. func (r *binaryDecoder) readString(tag int) (string, error) {
  139. switch {
  140. case tag >= 3 && tag <= len(token.SingleByteTokens):
  141. tok, err := token.GetSingleToken(tag)
  142. if err != nil {
  143. return "", err
  144. }
  145. if tok == "s.whatsapp.net" {
  146. tok = "c.us"
  147. }
  148. return tok, nil
  149. case tag == token.DICTIONARY_0 || tag == token.DICTIONARY_1 || tag == token.DICTIONARY_2 || tag == token.DICTIONARY_3:
  150. i, err := r.readInt8(false)
  151. if err != nil {
  152. return "", err
  153. }
  154. return token.GetDoubleToken(tag-token.DICTIONARY_0, i)
  155. case tag == token.LIST_EMPTY:
  156. return "", nil
  157. case tag == token.BINARY_8:
  158. length, err := r.readInt8(false)
  159. if err != nil {
  160. return "", err
  161. }
  162. return r.readStringFromChars(length)
  163. case tag == token.BINARY_20:
  164. length, err := r.readInt20()
  165. if err != nil {
  166. return "", err
  167. }
  168. return r.readStringFromChars(length)
  169. case tag == token.BINARY_32:
  170. length, err := r.readInt32(false)
  171. if err != nil {
  172. return "", err
  173. }
  174. return r.readStringFromChars(length)
  175. case tag == token.JID_PAIR:
  176. b, err := r.readByte()
  177. if err != nil {
  178. return "", err
  179. }
  180. i, err := r.readString(int(b))
  181. if err != nil {
  182. return "", err
  183. }
  184. b, err = r.readByte()
  185. if err != nil {
  186. return "", err
  187. }
  188. j, err := r.readString(int(b))
  189. if err != nil {
  190. return "", err
  191. }
  192. if i == "" || j == "" {
  193. return "", fmt.Errorf("invalid jid pair: %s - %s", i, j)
  194. }
  195. return i + "@" + j, nil
  196. case tag == token.NIBBLE_8 || tag == token.HEX_8:
  197. return r.readPacked8(tag)
  198. default:
  199. return "", fmt.Errorf("invalid string with tag %d", tag)
  200. }
  201. }
  202. func (r *binaryDecoder) readStringFromChars(length int) (string, error) {
  203. if err := r.checkEOS(length); err != nil {
  204. return "", err
  205. }
  206. ret := r.data[r.index : r.index+length]
  207. r.index += length
  208. return string(ret), nil
  209. }
  210. func (r *binaryDecoder) readAttributes(n int) (map[string]string, error) {
  211. if n == 0 {
  212. return nil, nil
  213. }
  214. ret := make(map[string]string)
  215. for i := 0; i < n; i++ {
  216. idx, err := r.readInt8(false)
  217. if err != nil {
  218. return nil, err
  219. }
  220. index, err := r.readString(idx)
  221. if err != nil {
  222. return nil, err
  223. }
  224. idx, err = r.readInt8(false)
  225. if err != nil {
  226. return nil, err
  227. }
  228. ret[index], err = r.readString(idx)
  229. if err != nil {
  230. return nil, err
  231. }
  232. }
  233. return ret, nil
  234. }
  235. func (r *binaryDecoder) readList(tag int) ([]Node, error) {
  236. size, err := r.readListSize(tag)
  237. if err != nil {
  238. return nil, err
  239. }
  240. ret := make([]Node, size)
  241. for i := 0; i < size; i++ {
  242. n, err := r.ReadNode()
  243. if err != nil {
  244. return nil, err
  245. }
  246. ret[i] = *n
  247. }
  248. return ret, nil
  249. }
  250. func (r *binaryDecoder) ReadNode() (*Node, error) {
  251. ret := &Node{}
  252. size, err := r.readInt8(false)
  253. if err != nil {
  254. return nil, err
  255. }
  256. listSize, err := r.readListSize(size)
  257. if err != nil {
  258. return nil, err
  259. }
  260. descrTag, err := r.readInt8(false)
  261. if descrTag == token.STREAM_END {
  262. return nil, fmt.Errorf("unexpected stream end")
  263. }
  264. ret.Description, err = r.readString(descrTag)
  265. if err != nil {
  266. return nil, err
  267. }
  268. if listSize == 0 || ret.Description == "" {
  269. return nil, fmt.Errorf("invalid Node")
  270. }
  271. ret.Attributes, err = r.readAttributes((listSize - 1) >> 1)
  272. if err != nil {
  273. return nil, err
  274. }
  275. if listSize%2 == 1 {
  276. return ret, nil
  277. }
  278. tag, err := r.readInt8(false)
  279. if err != nil {
  280. return nil, err
  281. }
  282. switch tag {
  283. case token.LIST_EMPTY, token.LIST_8, token.LIST_16:
  284. ret.Content, err = r.readList(tag)
  285. case token.BINARY_8:
  286. size, err = r.readInt8(false)
  287. if err != nil {
  288. return nil, err
  289. }
  290. ret.Content, err = r.readBytes(size)
  291. case token.BINARY_20:
  292. size, err = r.readInt20()
  293. if err != nil {
  294. return nil, err
  295. }
  296. ret.Content, err = r.readBytes(size)
  297. case token.BINARY_32:
  298. size, err = r.readInt32(false)
  299. if err != nil {
  300. return nil, err
  301. }
  302. ret.Content, err = r.readBytes(size)
  303. default:
  304. ret.Content, err = r.readString(tag)
  305. }
  306. if err != nil {
  307. return nil, err
  308. }
  309. return ret, nil
  310. }
  311. func (r *binaryDecoder) readBytes(n int) ([]byte, error) {
  312. ret := make([]byte, n)
  313. var err error
  314. for i := range ret {
  315. ret[i], err = r.readByte()
  316. if err != nil {
  317. return nil, err
  318. }
  319. }
  320. return ret, nil
  321. }