You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.2 KiB

  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. "golang.org/x/crypto/openpgp/errors"
  7. "io"
  8. )
  9. // Reader reads packets from an io.Reader and allows packets to be 'unread' so
  10. // that they result from the next call to Next.
  11. type Reader struct {
  12. q []Packet
  13. readers []io.Reader
  14. }
  15. // New io.Readers are pushed when a compressed or encrypted packet is processed
  16. // and recursively treated as a new source of packets. However, a carefully
  17. // crafted packet can trigger an infinite recursive sequence of packets. See
  18. // http://mumble.net/~campbell/misc/pgp-quine
  19. // https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4402
  20. // This constant limits the number of recursive packets that may be pushed.
  21. const maxReaders = 32
  22. // Next returns the most recently unread Packet, or reads another packet from
  23. // the top-most io.Reader. Unknown packet types are skipped.
  24. func (r *Reader) Next() (p Packet, err error) {
  25. if len(r.q) > 0 {
  26. p = r.q[len(r.q)-1]
  27. r.q = r.q[:len(r.q)-1]
  28. return
  29. }
  30. for len(r.readers) > 0 {
  31. p, err = Read(r.readers[len(r.readers)-1])
  32. if err == nil {
  33. return
  34. }
  35. if err == io.EOF {
  36. r.readers = r.readers[:len(r.readers)-1]
  37. continue
  38. }
  39. if _, ok := err.(errors.UnknownPacketTypeError); !ok {
  40. return nil, err
  41. }
  42. }
  43. return nil, io.EOF
  44. }
  45. // Push causes the Reader to start reading from a new io.Reader. When an EOF
  46. // error is seen from the new io.Reader, it is popped and the Reader continues
  47. // to read from the next most recent io.Reader. Push returns a StructuralError
  48. // if pushing the reader would exceed the maximum recursion level, otherwise it
  49. // returns nil.
  50. func (r *Reader) Push(reader io.Reader) (err error) {
  51. if len(r.readers) >= maxReaders {
  52. return errors.StructuralError("too many layers of packets")
  53. }
  54. r.readers = append(r.readers, reader)
  55. return nil
  56. }
  57. // Unread causes the given Packet to be returned from the next call to Next.
  58. func (r *Reader) Unread(p Packet) {
  59. r.q = append(r.q, p)
  60. }
  61. func NewReader(r io.Reader) *Reader {
  62. return &Reader{
  63. q: nil,
  64. readers: []io.Reader{r},
  65. }
  66. }