diff options
author | Loïc Hoguin <[email protected]> | 2018-01-23 16:14:18 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2018-01-23 16:14:18 +0100 |
commit | 482de55a96f9b68664a4d8b638f887138e26c5e8 (patch) | |
tree | 896c3398ec12777c7454cb2daef028a0e7a639ab /src/cowboy_iolists.erl | |
parent | 3a7b411143db08cb4d8813d00988c07848738bd3 (diff) | |
download | cowboy-482de55a96f9b68664a4d8b638f887138e26c5e8.tar.gz cowboy-482de55a96f9b68664a4d8b638f887138e26c5e8.tar.bz2 cowboy-482de55a96f9b68664a4d8b638f887138e26c5e8.zip |
Fix a miscount of output flow control window for HTTP/2
The miscount occurred because of a faulty iolist split function.
The bug should now be corrected, a PropEr test has been added
and a regression test has also been added.
Diffstat (limited to 'src/cowboy_iolists.erl')
-rw-r--r-- | src/cowboy_iolists.erl | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/cowboy_iolists.erl b/src/cowboy_iolists.erl index 51e0f33..d04d0ae 100644 --- a/src/cowboy_iolists.erl +++ b/src/cowboy_iolists.erl @@ -16,6 +16,10 @@ -export([split/2]). +-ifdef(TEST). +-include_lib("proper/include/proper.hrl"). +-endif. + -spec split(non_neg_integer(), iodata()) -> {iodata(), iodata()}. split(N, Iolist) -> case split(N, Iolist, []) of @@ -44,7 +48,13 @@ split(N, [Char|Tail], Acc) when is_integer(Char) -> split(N, [List|Tail], Acc0) -> case split(N, List, Acc0) of {ok, Before, After} -> - {ok, Before, [After|Tail]}; + IolistSize = iolist_size(Before), + if + IolistSize < N -> + split(N - IolistSize, [After|Tail], Before); + true -> + {ok, Before, [After|Tail]} + end; {more, More, Acc} -> split(More, Tail, Acc) end. @@ -60,7 +70,8 @@ split_test_() -> {10, "Hello!", "Hello!", ""}, {10, <<"Hello!">>, "Hello!", ""}, {10, ["He", [<<"ll">>], $o, [["!"]]], "Hello!", ""}, - {10, ["Hel"|<<"lo!">>], "Hello!", ""} + {10, ["Hel"|<<"lo!">>], "Hello!", ""}, + {10, [[<<>>|<<>>], [], <<"Hello world!">>], "Hello worl", "d!"} ], [{iolist_to_binary(V), fun() -> {B, A} = split(N, V), @@ -68,4 +79,21 @@ split_test_() -> true = iolist_to_binary(RA) =:= iolist_to_binary(A) end} || {N, V, RB, RA} <- Tests]. +prop_split_test() -> + ?FORALL({N, Input}, + {non_neg_integer(), iolist()}, + begin + Size = iolist_size(Input), + {Before, After} = split(N, Input), + if + N >= Size -> + ((iolist_size(After) =:= 0) + andalso iolist_to_binary(Before) =:= iolist_to_binary(Input)); + true -> + <<ExpectBefore:N/binary, ExpectAfter/bits>> = iolist_to_binary(Input), + (ExpectBefore =:= iolist_to_binary(Before)) + andalso (ExpectAfter =:= iolist_to_binary(After)) + end + end). + -endif. |