aboutsummaryrefslogtreecommitdiffstats
path: root/src/cow_http2.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2017-02-25 20:02:41 +0100
committerLoïc Hoguin <[email protected]>2017-02-25 20:02:41 +0100
commit462c01f808dccec8ce00ea53b02146894c0dbc6c (patch)
tree6e31cb98d929c7f3ca75f05f3d7afcd1003db1de /src/cow_http2.erl
parent5fd9d5e850354a73f7699fc594b0528dc744404b (diff)
downloadcowlib-462c01f808dccec8ce00ea53b02146894c0dbc6c.tar.gz
cowlib-462c01f808dccec8ce00ea53b02146894c0dbc6c.tar.bz2
cowlib-462c01f808dccec8ce00ea53b02146894c0dbc6c.zip
Add frame size related error cases to cow_http2:parse
Diffstat (limited to 'src/cow_http2.erl')
-rw-r--r--src/cow_http2.erl26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/cow_http2.erl b/src/cow_http2.erl
index 4b4600f..91e6985 100644
--- a/src/cow_http2.erl
+++ b/src/cow_http2.erl
@@ -16,6 +16,7 @@
%% Parsing.
-export([parse/1]).
+-export([parse/2]).
-export([parse_settings_payload/1]).
%% Building.
@@ -73,11 +74,18 @@
%% Parsing.
+parse(<< Len:24, _/bits >>, MaxFrameSize) when Len > MaxFrameSize ->
+ {connection_error, frame_size_error, 'The frame size exceeded SETTINGS_MAX_FRAME_SIZE. (RFC7540 4.2)'};
+parse(Data, _) ->
+ parse(Data).
+
%%
%% DATA frames.
%%
parse(<< _:24, 0:8, _:9, 0:31, _/bits >>) ->
{connection_error, protocol_error, 'DATA frames MUST be associated with a stream. (RFC7540 6.1)'};
+parse(<< 0:24, 0:8, _:4, 1:1, _:35, _/bits >>) ->
+ {connection_error, frame_size_error, 'DATA frames with padding flag MUST have a length > 0. (RFC7540 6.1)'};
parse(<< Len0:24, 0:8, _:4, 1:1, _:35, PadLen:8, _/bits >>) when PadLen >= Len0 ->
{connection_error, protocol_error, 'Length of padding MUST be less than length of payload. (RFC7540 6.1)'};
%% No padding.
@@ -98,6 +106,12 @@ parse(<< Len0:24, 0:8, _:4, 1:1, _:2, FlagEndStream:1, _:1, StreamID:31, PadLen:
%%
parse(<< _:24, 1:8, _:9, 0:31, _/bits >>) ->
{connection_error, protocol_error, 'HEADERS frames MUST be associated with a stream. (RFC7540 6.2)'};
+parse(<< 0:24, 1:8, _:4, 1:1, _:35, _/bits >>) ->
+ {connection_error, frame_size_error, 'HEADERS frames with padding flag MUST have a length > 0. (RFC7540 6.1)'};
+parse(<< Len:24, 1:8, _:2, 1:1, _:37, _/bits >>) when Len < 5 ->
+ {connection_error, frame_size_error, 'HEADERS frames with priority flag MUST have a length >= 5. (RFC7540 6.1)'};
+parse(<< Len:24, 1:8, _:2, 1:1, _:37, _/bits >>) when Len < 6 ->
+ {connection_error, frame_size_error, 'HEADERS frames with padding and priority flags MUST have a length >= 6. (RFC7540 6.1)'};
parse(<< Len0:24, 1:8, _:4, 1:1, _:35, PadLen:8, _/bits >>) when PadLen >= Len0 ->
{connection_error, protocol_error, 'Length of padding MUST be less than length of payload. (RFC7540 6.2)'};
parse(<< Len0:24, 1:8, _:2, 1:1, _:1, 1:1, _:35, PadLen:8, _/bits >>) when PadLen >= Len0 - 5 ->
@@ -154,8 +168,8 @@ parse(<< 4:24, 3:8, _:9, 0:31, _/bits >>) ->
parse(<< 4:24, 3:8, _:9, StreamID:31, ErrorCode:32, Rest/bits >>) ->
{ok, {rst_stream, StreamID, parse_error_code(ErrorCode)}, Rest};
%% @todo same as priority
-parse(<< BadLen:24, 3:8, _:9, StreamID:31, _:BadLen/binary, Rest/bits >>) ->
- {stream_error, StreamID, frame_size_error, 'RST_STREAM frames MUST be 4 bytes wide. (RFC7540 6.4)', Rest};
+parse(<< _:24, 3:8, _:9, _:31, _/bits >>) ->
+ {connection_error, frame_size_error, 'RST_STREAM frames MUST be 4 bytes wide. (RFC7540 6.4)'};
%%
%% SETTINGS frames.
%%
@@ -172,8 +186,14 @@ parse(<< _:24, 4:8, _/bits >>) ->
%%
%% PUSH_PROMISE frames.
%%
+parse(<< Len:24, 5:8, _:40, _/bits >>) when Len < 4 ->
+ {connection_error, frame_size_error, 'PUSH_PROMISE frames MUST have a length >= 4. (RFC7540 4.2, RFC7540 6.6)'};
+parse(<< Len:24, 5:8, _:4, 1:1, _:35, _/bits >>) when Len < 5 ->
+ {connection_error, frame_size_error, 'PUSH_PROMISE frames with padding flag MUST have a length >= 5. (RFC7540 4.2, RFC7540 6.6)'};
parse(<< _:24, 5:8, _:9, 0:31, _/bits >>) ->
{connection_error, protocol_error, 'PUSH_PROMISE frames MUST be associated with a stream. (RFC7540 6.6)'};
+parse(<< Len0:24, 5:8, _:4, 1:1, _:35, PadLen:8, _/bits >>) when PadLen >= Len0 - 4 ->
+ {connection_error, protocol_error, 'Length of padding MUST be less than length of payload. (RFC7540 6.6)'};
parse(<< Len0:24, 5:8, _:4, 0:1, FlagEndHeaders:1, _:3, StreamID:31, _:1, PromisedStreamID:31, Rest0/bits >>)
when byte_size(Rest0) >= Len0 - 4 ->
Len = Len0 - 4,
@@ -206,6 +226,8 @@ parse(<< Len0:24, 7:8, _:9, 0:31, _:1, LastStreamID:31, ErrorCode:32, Rest0/bits
Len = Len0 - 8,
<< DebugData:Len/binary, Rest/bits >> = Rest0,
{ok, {goaway, LastStreamID, parse_error_code(ErrorCode), DebugData}, Rest};
+parse(<< Len:24, 7:8, _:40, _/bits >>) when Len < 8 ->
+ {connection_error, frame_size_error, 'GOAWAY frames MUST have a length >= 8. (RFC7540 4.2, RFC7540 6.8)'};
parse(<< _:24, 7:8, _:40, _/bits >>) ->
{connection_error, protocol_error, 'GOAWAY frames MUST NOT be associated with a stream. (RFC7540 6.8)'};
%%