diff --git a/vlib/net/http/chunked/dechunk.v b/vlib/net/http/chunked/dechunk.v index 44f251231b..a4c30f368e 100644 --- a/vlib/net/http/chunked/dechunk.v +++ b/vlib/net/http/chunked/dechunk.v @@ -46,13 +46,16 @@ fn (mut s ChunkScanner) skip_crlf() { s.pos += 2 } -fn (mut s ChunkScanner) read_chunk(chunksize u32) string { +fn (mut s ChunkScanner) read_chunk(chunksize u32) !string { startpos := s.pos s.pos += int(chunksize) + if s.pos > s.text.len { + return error('invalid chunksize') + } return s.text[startpos..s.pos] } -pub fn decode(text string) string { +pub fn decode(text string) !string { mut sb := strings.new_builder(100) mut cscanner := ChunkScanner{ pos: 0 @@ -64,7 +67,8 @@ pub fn decode(text string) string { break } cscanner.skip_crlf() - sb.write_string(cscanner.read_chunk(csize)) + ch := cscanner.read_chunk(csize)! + sb.write_string(ch) cscanner.skip_crlf() } cscanner.skip_crlf() diff --git a/vlib/net/http/chunked/dechunk_test.v b/vlib/net/http/chunked/dechunk_test.v new file mode 100644 index 0000000000..0d9822453b --- /dev/null +++ b/vlib/net/http/chunked/dechunk_test.v @@ -0,0 +1,16 @@ +module chunked + +fn test_invalid_chunk() { + mut is_failure := false + + decode('eee') or { is_failure = true } + + assert is_failure +} + +fn test_valid_chunk() { + chunks := '4\r\nWiki\r\n7\r\npedia i\r\nB\r\nn \r\nchunks.\r\n0\r\n\r\n' + str := decode(chunks) or { panic('uh oh') } + + assert str == 'Wikipedia in \r\nchunks.' +} diff --git a/vlib/net/http/response.v b/vlib/net/http/response.v index d9819a78aa..10720efd1a 100644 --- a/vlib/net/http/response.v +++ b/vlib/net/http/response.v @@ -42,7 +42,7 @@ pub fn parse_response(resp string) !Response { header := parse_headers(resp.substr(start_idx, end_idx))! mut body := resp.substr(end_idx, resp.len) if header.get(.transfer_encoding) or { '' } == 'chunked' { - body = chunked.decode(body) + body = chunked.decode(body)! } return Response{ http_version: version