aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2015-08-13 03:40:31 +0900
committerKazuki Yamaguchi <k@rhe.jp>2015-08-13 03:40:31 +0900
commit8a5541d786022e118d73e2cab4e2d985c4a45842 (patch)
tree91dd3621db6422b1b5e34aa4c2c422d5c54abd6a /lib
parenta429578603c30eb205136b00b90cf0ac640f9173 (diff)
downloadplum-8a5541d786022e118d73e2cab4e2d985c4a45842.tar.gz
hpack: raise error if buffer is incomplete
Diffstat (limited to 'lib')
-rw-r--r--lib/plum/hpack/decoder.rb24
1 files changed, 17 insertions, 7 deletions
diff --git a/lib/plum/hpack/decoder.rb b/lib/plum/hpack/decoder.rb
index adc34e5..71c8be5 100644
--- a/lib/plum/hpack/decoder.rb
+++ b/lib/plum/hpack/decoder.rb
@@ -32,24 +32,34 @@ module Plum
end
def read_integer!(str, prefix_length)
+ first_byte = str.byteshift(1).uint8
+ raise HPACKError.new("integer: end of buffer") unless first_byte
+
mask = (1 << prefix_length) - 1
- ret = str.byteshift(1).uint8 & mask
+ ret = first_byte & mask
+ return ret if ret < mask
+
+ octets = 0
+ while next_value = str.byteshift(1).uint8
+ ret += (next_value & 0b01111111) << (7 * octets)
+ octets += 1
- if ret == mask
- loop.with_index do |_, i|
- next_value = str.byteshift(1).uint8
- ret += (next_value & ~(0b10000000)) << (7 * i)
- break if next_value & 0b10000000 == 0
+ if next_value < 128
+ return ret
+ elsif octets == 4 # RFC 7541 5.1 tells us that we MUST have limitation. at least > 2 ** 28
+ raise HPACKError.new("integer: too large integer")
end
end
- ret
+ raise HPACKError.new("integer: end of buffer")
end
def read_string!(str)
huffman = (str.uint8 >> 7) == 1
length = read_integer!(str, 7)
bin = str.byteshift(length)
+
+ raise HTTPError.new("string: end of buffer") if bin.bytesize < length
bin = Huffman.decode(bin) if huffman
bin
end