aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_iolists.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-01-23 16:14:18 +0100
committerLoïc Hoguin <[email protected]>2018-01-23 16:14:18 +0100
commit482de55a96f9b68664a4d8b638f887138e26c5e8 (patch)
tree896c3398ec12777c7454cb2daef028a0e7a639ab /src/cowboy_iolists.erl
parent3a7b411143db08cb4d8813d00988c07848738bd3 (diff)
downloadcowboy-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.erl32
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.