packet_test.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package packet
  5. import (
  6. "bytes"
  7. "encoding/hex"
  8. "fmt"
  9. "golang.org/x/crypto/openpgp/errors"
  10. "io"
  11. "io/ioutil"
  12. "testing"
  13. )
  14. func TestReadFull(t *testing.T) {
  15. var out [4]byte
  16. b := bytes.NewBufferString("foo")
  17. n, err := readFull(b, out[:3])
  18. if n != 3 || err != nil {
  19. t.Errorf("full read failed n:%d err:%s", n, err)
  20. }
  21. b = bytes.NewBufferString("foo")
  22. n, err = readFull(b, out[:4])
  23. if n != 3 || err != io.ErrUnexpectedEOF {
  24. t.Errorf("partial read failed n:%d err:%s", n, err)
  25. }
  26. b = bytes.NewBuffer(nil)
  27. n, err = readFull(b, out[:3])
  28. if n != 0 || err != io.ErrUnexpectedEOF {
  29. t.Errorf("empty read failed n:%d err:%s", n, err)
  30. }
  31. }
  32. func readerFromHex(s string) io.Reader {
  33. data, err := hex.DecodeString(s)
  34. if err != nil {
  35. panic("readerFromHex: bad input")
  36. }
  37. return bytes.NewBuffer(data)
  38. }
  39. var readLengthTests = []struct {
  40. hexInput string
  41. length int64
  42. isPartial bool
  43. err error
  44. }{
  45. {"", 0, false, io.ErrUnexpectedEOF},
  46. {"1f", 31, false, nil},
  47. {"c0", 0, false, io.ErrUnexpectedEOF},
  48. {"c101", 256 + 1 + 192, false, nil},
  49. {"e0", 1, true, nil},
  50. {"e1", 2, true, nil},
  51. {"e2", 4, true, nil},
  52. {"ff", 0, false, io.ErrUnexpectedEOF},
  53. {"ff00", 0, false, io.ErrUnexpectedEOF},
  54. {"ff0000", 0, false, io.ErrUnexpectedEOF},
  55. {"ff000000", 0, false, io.ErrUnexpectedEOF},
  56. {"ff00000000", 0, false, nil},
  57. {"ff01020304", 16909060, false, nil},
  58. }
  59. func TestReadLength(t *testing.T) {
  60. for i, test := range readLengthTests {
  61. length, isPartial, err := readLength(readerFromHex(test.hexInput))
  62. if test.err != nil {
  63. if err != test.err {
  64. t.Errorf("%d: expected different error got:%s want:%s", i, err, test.err)
  65. }
  66. continue
  67. }
  68. if err != nil {
  69. t.Errorf("%d: unexpected error: %s", i, err)
  70. continue
  71. }
  72. if length != test.length || isPartial != test.isPartial {
  73. t.Errorf("%d: bad result got:(%d,%t) want:(%d,%t)", i, length, isPartial, test.length, test.isPartial)
  74. }
  75. }
  76. }
  77. var partialLengthReaderTests = []struct {
  78. hexInput string
  79. err error
  80. hexOutput string
  81. }{
  82. {"e0", io.ErrUnexpectedEOF, ""},
  83. {"e001", io.ErrUnexpectedEOF, ""},
  84. {"e0010102", nil, "0102"},
  85. {"ff00000000", nil, ""},
  86. {"e10102e1030400", nil, "01020304"},
  87. {"e101", io.ErrUnexpectedEOF, ""},
  88. }
  89. func TestPartialLengthReader(t *testing.T) {
  90. for i, test := range partialLengthReaderTests {
  91. r := &partialLengthReader{readerFromHex(test.hexInput), 0, true}
  92. out, err := ioutil.ReadAll(r)
  93. if test.err != nil {
  94. if err != test.err {
  95. t.Errorf("%d: expected different error got:%s want:%s", i, err, test.err)
  96. }
  97. continue
  98. }
  99. if err != nil {
  100. t.Errorf("%d: unexpected error: %s", i, err)
  101. continue
  102. }
  103. got := fmt.Sprintf("%x", out)
  104. if got != test.hexOutput {
  105. t.Errorf("%d: got:%s want:%s", i, test.hexOutput, got)
  106. }
  107. }
  108. }
  109. var readHeaderTests = []struct {
  110. hexInput string
  111. structuralError bool
  112. unexpectedEOF bool
  113. tag int
  114. length int64
  115. hexOutput string
  116. }{
  117. {"", false, false, 0, 0, ""},
  118. {"7f", true, false, 0, 0, ""},
  119. // Old format headers
  120. {"80", false, true, 0, 0, ""},
  121. {"8001", false, true, 0, 1, ""},
  122. {"800102", false, false, 0, 1, "02"},
  123. {"81000102", false, false, 0, 1, "02"},
  124. {"820000000102", false, false, 0, 1, "02"},
  125. {"860000000102", false, false, 1, 1, "02"},
  126. {"83010203", false, false, 0, -1, "010203"},
  127. // New format headers
  128. {"c0", false, true, 0, 0, ""},
  129. {"c000", false, false, 0, 0, ""},
  130. {"c00102", false, false, 0, 1, "02"},
  131. {"c0020203", false, false, 0, 2, "0203"},
  132. {"c00202", false, true, 0, 2, ""},
  133. {"c3020203", false, false, 3, 2, "0203"},
  134. }
  135. func TestReadHeader(t *testing.T) {
  136. for i, test := range readHeaderTests {
  137. tag, length, contents, err := readHeader(readerFromHex(test.hexInput))
  138. if test.structuralError {
  139. if _, ok := err.(errors.StructuralError); ok {
  140. continue
  141. }
  142. t.Errorf("%d: expected StructuralError, got:%s", i, err)
  143. continue
  144. }
  145. if err != nil {
  146. if len(test.hexInput) == 0 && err == io.EOF {
  147. continue
  148. }
  149. if !test.unexpectedEOF || err != io.ErrUnexpectedEOF {
  150. t.Errorf("%d: unexpected error from readHeader: %s", i, err)
  151. }
  152. continue
  153. }
  154. if int(tag) != test.tag || length != test.length {
  155. t.Errorf("%d: got:(%d,%d) want:(%d,%d)", i, int(tag), length, test.tag, test.length)
  156. continue
  157. }
  158. body, err := ioutil.ReadAll(contents)
  159. if err != nil {
  160. if !test.unexpectedEOF || err != io.ErrUnexpectedEOF {
  161. t.Errorf("%d: unexpected error from contents: %s", i, err)
  162. }
  163. continue
  164. }
  165. if test.unexpectedEOF {
  166. t.Errorf("%d: expected ErrUnexpectedEOF from contents but got no error", i)
  167. continue
  168. }
  169. got := fmt.Sprintf("%x", body)
  170. if got != test.hexOutput {
  171. t.Errorf("%d: got:%s want:%s", i, got, test.hexOutput)
  172. }
  173. }
  174. }
  175. func TestSerializeHeader(t *testing.T) {
  176. tag := packetTypePublicKey
  177. lengths := []int{0, 1, 2, 64, 192, 193, 8000, 8384, 8385, 10000}
  178. for _, length := range lengths {
  179. buf := bytes.NewBuffer(nil)
  180. serializeHeader(buf, tag, length)
  181. tag2, length2, _, err := readHeader(buf)
  182. if err != nil {
  183. t.Errorf("length %d, err: %s", length, err)
  184. }
  185. if tag2 != tag {
  186. t.Errorf("length %d, tag incorrect (got %d, want %d)", length, tag2, tag)
  187. }
  188. if int(length2) != length {
  189. t.Errorf("length %d, length incorrect (got %d)", length, length2)
  190. }
  191. }
  192. }
  193. func TestPartialLengths(t *testing.T) {
  194. buf := bytes.NewBuffer(nil)
  195. w := new(partialLengthWriter)
  196. w.w = noOpCloser{buf}
  197. const maxChunkSize = 64
  198. var b [maxChunkSize]byte
  199. var n uint8
  200. for l := 1; l <= maxChunkSize; l++ {
  201. for i := 0; i < l; i++ {
  202. b[i] = n
  203. n++
  204. }
  205. m, err := w.Write(b[:l])
  206. if m != l {
  207. t.Errorf("short write got: %d want: %d", m, l)
  208. }
  209. if err != nil {
  210. t.Errorf("error from write: %s", err)
  211. }
  212. }
  213. w.Close()
  214. want := (maxChunkSize * (maxChunkSize + 1)) / 2
  215. copyBuf := bytes.NewBuffer(nil)
  216. r := &partialLengthReader{buf, 0, true}
  217. m, err := io.Copy(copyBuf, r)
  218. if m != int64(want) {
  219. t.Errorf("short copy got: %d want: %d", m, want)
  220. }
  221. if err != nil {
  222. t.Errorf("error from copy: %s", err)
  223. }
  224. copyBytes := copyBuf.Bytes()
  225. for i := 0; i < want; i++ {
  226. if copyBytes[i] != uint8(i) {
  227. t.Errorf("bad pattern in copy at %d", i)
  228. break
  229. }
  230. }
  231. }