length.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package ber
  2. import (
  3. "errors"
  4. "fmt"
  5. "io"
  6. )
  7. func readLength(reader io.Reader) (length int, read int, err error) {
  8. // length byte
  9. b, err := readByte(reader)
  10. if err != nil {
  11. if Debug {
  12. fmt.Printf("error reading length byte: %v\n", err)
  13. }
  14. return 0, 0, err
  15. }
  16. read++
  17. switch {
  18. case b == 0xFF:
  19. // Invalid 0xFF (x.600, 8.1.3.5.c)
  20. return 0, read, errors.New("invalid length byte 0xff")
  21. case b == LengthLongFormBitmask:
  22. // Indefinite form, we have to decode packets until we encounter an EOC packet (x.600, 8.1.3.6)
  23. length = LengthIndefinite
  24. case b&LengthLongFormBitmask == 0:
  25. // Short definite form, extract the length from the bottom 7 bits (x.600, 8.1.3.4)
  26. length = int(b) & LengthValueBitmask
  27. case b&LengthLongFormBitmask != 0:
  28. // Long definite form, extract the number of length bytes to follow from the bottom 7 bits (x.600, 8.1.3.5.b)
  29. lengthBytes := int(b) & LengthValueBitmask
  30. // Protect against overflow
  31. // TODO: support big int length?
  32. if lengthBytes > 8 {
  33. return 0, read, errors.New("long-form length overflow")
  34. }
  35. // Accumulate into a 64-bit variable
  36. var length64 int64
  37. for i := 0; i < lengthBytes; i++ {
  38. b, err = readByte(reader)
  39. if err != nil {
  40. if Debug {
  41. fmt.Printf("error reading long-form length byte %d: %v\n", i, err)
  42. }
  43. return 0, read, err
  44. }
  45. read++
  46. // x.600, 8.1.3.5
  47. length64 <<= 8
  48. length64 |= int64(b)
  49. }
  50. // Cast to a platform-specific integer
  51. length = int(length64)
  52. // Ensure we didn't overflow
  53. if int64(length) != length64 {
  54. return 0, read, errors.New("long-form length overflow")
  55. }
  56. default:
  57. return 0, read, errors.New("invalid length byte")
  58. }
  59. return length, read, nil
  60. }
  61. func encodeLength(length int) []byte {
  62. length_bytes := encodeUnsignedInteger(uint64(length))
  63. if length > 127 || len(length_bytes) > 1 {
  64. longFormBytes := []byte{(LengthLongFormBitmask | byte(len(length_bytes)))}
  65. longFormBytes = append(longFormBytes, length_bytes...)
  66. length_bytes = longFormBytes
  67. }
  68. return length_bytes
  69. }