1package sarama 2 3import ( 4 "encoding/binary" 5 "math" 6) 7 8var errInvalidArrayLength = PacketDecodingError{"invalid array length"} 9var errInvalidByteSliceLength = PacketDecodingError{"invalid byteslice length"} 10var errInvalidStringLength = PacketDecodingError{"invalid string length"} 11var errVarintOverflow = PacketDecodingError{"varint overflow"} 12var errUVarintOverflow = PacketDecodingError{"uvarint overflow"} 13var errInvalidBool = PacketDecodingError{"invalid bool"} 14var errUnsupportedTaggedFields = PacketDecodingError{"non-empty tagged fields are not supported yet"} 15 16type realDecoder struct { 17 raw []byte 18 off int 19 stack []pushDecoder 20} 21 22// primitives 23 24func (rd *realDecoder) getInt8() (int8, error) { 25 if rd.remaining() < 1 { 26 rd.off = len(rd.raw) 27 return -1, ErrInsufficientData 28 } 29 tmp := int8(rd.raw[rd.off]) 30 rd.off++ 31 return tmp, nil 32} 33 34func (rd *realDecoder) getInt16() (int16, error) { 35 if rd.remaining() < 2 { 36 rd.off = len(rd.raw) 37 return -1, ErrInsufficientData 38 } 39 tmp := int16(binary.BigEndian.Uint16(rd.raw[rd.off:])) 40 rd.off += 2 41 return tmp, nil 42} 43 44func (rd *realDecoder) getInt32() (int32, error) { 45 if rd.remaining() < 4 { 46 rd.off = len(rd.raw) 47 return -1, ErrInsufficientData 48 } 49 tmp := int32(binary.BigEndian.Uint32(rd.raw[rd.off:])) 50 rd.off += 4 51 return tmp, nil 52} 53 54func (rd *realDecoder) getInt64() (int64, error) { 55 if rd.remaining() < 8 { 56 rd.off = len(rd.raw) 57 return -1, ErrInsufficientData 58 } 59 tmp := int64(binary.BigEndian.Uint64(rd.raw[rd.off:])) 60 rd.off += 8 61 return tmp, nil 62} 63 64func (rd *realDecoder) getVarint() (int64, error) { 65 tmp, n := binary.Varint(rd.raw[rd.off:]) 66 if n == 0 { 67 rd.off = len(rd.raw) 68 return -1, ErrInsufficientData 69 } 70 if n < 0 { 71 rd.off -= n 72 return -1, errVarintOverflow 73 } 74 rd.off += n 75 return tmp, nil 76} 77 78func (rd *realDecoder) getUVarint() (uint64, error) { 79 tmp, n := binary.Uvarint(rd.raw[rd.off:]) 80 if n == 0 { 81 rd.off = len(rd.raw) 82 return 0, ErrInsufficientData 83 } 84 85 if n < 0 { 86 rd.off -= n 87 return 0, errUVarintOverflow 88 } 89 90 rd.off += n 91 return tmp, nil 92} 93 94func (rd *realDecoder) getArrayLength() (int, error) { 95 if rd.remaining() < 4 { 96 rd.off = len(rd.raw) 97 return -1, ErrInsufficientData 98 } 99 tmp := int(int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))) 100 rd.off += 4 101 if tmp > rd.remaining() { 102 rd.off = len(rd.raw) 103 return -1, ErrInsufficientData 104 } else if tmp > 2*math.MaxUint16 { 105 return -1, errInvalidArrayLength 106 } 107 return tmp, nil 108} 109 110func (rd *realDecoder) getCompactArrayLength() (int, error) { 111 n, err := rd.getUVarint() 112 if err != nil { 113 return 0, err 114 } 115 116 if n == 0 { 117 return 0, nil 118 } 119 120 return int(n) - 1, nil 121} 122 123func (rd *realDecoder) getBool() (bool, error) { 124 b, err := rd.getInt8() 125 if err != nil || b == 0 { 126 return false, err 127 } 128 if b != 1 { 129 return false, errInvalidBool 130 } 131 return true, nil 132} 133 134func (rd *realDecoder) getEmptyTaggedFieldArray() (int, error) { 135 tagCount, err := rd.getUVarint() 136 if err != nil { 137 return 0, err 138 } 139 140 if tagCount != 0 { 141 return 0, errUnsupportedTaggedFields 142 } 143 144 return 0, nil 145} 146 147// collections 148 149func (rd *realDecoder) getBytes() ([]byte, error) { 150 tmp, err := rd.getInt32() 151 if err != nil { 152 return nil, err 153 } 154 if tmp == -1 { 155 return nil, nil 156 } 157 158 return rd.getRawBytes(int(tmp)) 159} 160 161func (rd *realDecoder) getVarintBytes() ([]byte, error) { 162 tmp, err := rd.getVarint() 163 if err != nil { 164 return nil, err 165 } 166 if tmp == -1 { 167 return nil, nil 168 } 169 170 return rd.getRawBytes(int(tmp)) 171} 172 173func (rd *realDecoder) getStringLength() (int, error) { 174 length, err := rd.getInt16() 175 if err != nil { 176 return 0, err 177 } 178 179 n := int(length) 180 181 switch { 182 case n < -1: 183 return 0, errInvalidStringLength 184 case n > rd.remaining(): 185 rd.off = len(rd.raw) 186 return 0, ErrInsufficientData 187 } 188 189 return n, nil 190} 191 192func (rd *realDecoder) getString() (string, error) { 193 n, err := rd.getStringLength() 194 if err != nil || n == -1 { 195 return "", err 196 } 197 198 tmpStr := string(rd.raw[rd.off : rd.off+n]) 199 rd.off += n 200 return tmpStr, nil 201} 202 203func (rd *realDecoder) getNullableString() (*string, error) { 204 n, err := rd.getStringLength() 205 if err != nil || n == -1 { 206 return nil, err 207 } 208 209 tmpStr := string(rd.raw[rd.off : rd.off+n]) 210 rd.off += n 211 return &tmpStr, err 212} 213 214func (rd *realDecoder) getCompactString() (string, error) { 215 n, err := rd.getUVarint() 216 if err != nil { 217 return "", err 218 } 219 220 var length = int(n - 1) 221 222 tmpStr := string(rd.raw[rd.off : rd.off+length]) 223 rd.off += length 224 return tmpStr, nil 225} 226 227func (rd *realDecoder) getCompactNullableString() (*string, error) { 228 n, err := rd.getUVarint() 229 230 if err != nil { 231 return nil, err 232 } 233 234 var length = int(n - 1) 235 236 if length < 0 { 237 return nil, err 238 } 239 240 tmpStr := string(rd.raw[rd.off : rd.off+length]) 241 rd.off += length 242 return &tmpStr, err 243} 244 245func (rd *realDecoder) getCompactInt32Array() ([]int32, error) { 246 n, err := rd.getUVarint() 247 if err != nil { 248 return nil, err 249 } 250 251 if n == 0 { 252 return nil, nil 253 } 254 255 arrayLength := int(n) - 1 256 257 ret := make([]int32, arrayLength) 258 259 for i := range ret { 260 ret[i] = int32(binary.BigEndian.Uint32(rd.raw[rd.off:])) 261 rd.off += 4 262 } 263 return ret, nil 264} 265 266func (rd *realDecoder) getInt32Array() ([]int32, error) { 267 if rd.remaining() < 4 { 268 rd.off = len(rd.raw) 269 return nil, ErrInsufficientData 270 } 271 n := int(binary.BigEndian.Uint32(rd.raw[rd.off:])) 272 rd.off += 4 273 274 if rd.remaining() < 4*n { 275 rd.off = len(rd.raw) 276 return nil, ErrInsufficientData 277 } 278 279 if n == 0 { 280 return nil, nil 281 } 282 283 if n < 0 { 284 return nil, errInvalidArrayLength 285 } 286 287 ret := make([]int32, n) 288 for i := range ret { 289 ret[i] = int32(binary.BigEndian.Uint32(rd.raw[rd.off:])) 290 rd.off += 4 291 } 292 return ret, nil 293} 294 295func (rd *realDecoder) getInt64Array() ([]int64, error) { 296 if rd.remaining() < 4 { 297 rd.off = len(rd.raw) 298 return nil, ErrInsufficientData 299 } 300 n := int(binary.BigEndian.Uint32(rd.raw[rd.off:])) 301 rd.off += 4 302 303 if rd.remaining() < 8*n { 304 rd.off = len(rd.raw) 305 return nil, ErrInsufficientData 306 } 307 308 if n == 0 { 309 return nil, nil 310 } 311 312 if n < 0 { 313 return nil, errInvalidArrayLength 314 } 315 316 ret := make([]int64, n) 317 for i := range ret { 318 ret[i] = int64(binary.BigEndian.Uint64(rd.raw[rd.off:])) 319 rd.off += 8 320 } 321 return ret, nil 322} 323 324func (rd *realDecoder) getStringArray() ([]string, error) { 325 if rd.remaining() < 4 { 326 rd.off = len(rd.raw) 327 return nil, ErrInsufficientData 328 } 329 n := int(binary.BigEndian.Uint32(rd.raw[rd.off:])) 330 rd.off += 4 331 332 if n == 0 { 333 return nil, nil 334 } 335 336 if n < 0 { 337 return nil, errInvalidArrayLength 338 } 339 340 ret := make([]string, n) 341 for i := range ret { 342 str, err := rd.getString() 343 if err != nil { 344 return nil, err 345 } 346 347 ret[i] = str 348 } 349 return ret, nil 350} 351 352// subsets 353 354func (rd *realDecoder) remaining() int { 355 return len(rd.raw) - rd.off 356} 357 358func (rd *realDecoder) getSubset(length int) (packetDecoder, error) { 359 buf, err := rd.getRawBytes(length) 360 if err != nil { 361 return nil, err 362 } 363 return &realDecoder{raw: buf}, nil 364} 365 366func (rd *realDecoder) getRawBytes(length int) ([]byte, error) { 367 if length < 0 { 368 return nil, errInvalidByteSliceLength 369 } else if length > rd.remaining() { 370 rd.off = len(rd.raw) 371 return nil, ErrInsufficientData 372 } 373 374 start := rd.off 375 rd.off += length 376 return rd.raw[start:rd.off], nil 377} 378 379func (rd *realDecoder) peek(offset, length int) (packetDecoder, error) { 380 if rd.remaining() < offset+length { 381 return nil, ErrInsufficientData 382 } 383 off := rd.off + offset 384 return &realDecoder{raw: rd.raw[off : off+length]}, nil 385} 386 387func (rd *realDecoder) peekInt8(offset int) (int8, error) { 388 const byteLen = 1 389 if rd.remaining() < offset+byteLen { 390 return -1, ErrInsufficientData 391 } 392 return int8(rd.raw[rd.off+offset]), nil 393} 394 395// stacks 396 397func (rd *realDecoder) push(in pushDecoder) error { 398 in.saveOffset(rd.off) 399 400 var reserve int 401 if dpd, ok := in.(dynamicPushDecoder); ok { 402 if err := dpd.decode(rd); err != nil { 403 return err 404 } 405 } else { 406 reserve = in.reserveLength() 407 if rd.remaining() < reserve { 408 rd.off = len(rd.raw) 409 return ErrInsufficientData 410 } 411 } 412 413 rd.stack = append(rd.stack, in) 414 415 rd.off += reserve 416 417 return nil 418} 419 420func (rd *realDecoder) pop() error { 421 // this is go's ugly pop pattern (the inverse of append) 422 in := rd.stack[len(rd.stack)-1] 423 rd.stack = rd.stack[:len(rd.stack)-1] 424 425 return in.check(rd.off, rd.raw) 426} 427