From 41f3bdc9a9ee88c32ea576bd6a99ee122b4ad4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 25 Mar 2019 10:16:55 +0100 Subject: Make sure iolist split uses N length The previous implementation would return "ok" under certain situations when more data could be fit into the buffer. By making "ok" explicitly mean length is 0, then we can simplify other parts of the codebase and fix a bug that could cause us to send less data then desired over the wire. --- src/cow_iolists.erl | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/cow_iolists.erl b/src/cow_iolists.erl index 41e6503..dcb48d7 100644 --- a/src/cow_iolists.erl +++ b/src/cow_iolists.erl @@ -34,7 +34,7 @@ split(0, Rest, Acc) -> split(N, [], Acc) -> {more, N, Acc}; split(N, Binary, Acc) when byte_size(Binary) =< N -> - {ok, lists:reverse([Binary|Acc]), <<>>}; + {more, N - byte_size(Binary), [Binary|Acc]}; split(N, Binary, Acc) when is_binary(Binary) -> << Before:N/binary, After/bits >> = Binary, {ok, lists:reverse([Before|Acc]), After}; @@ -48,13 +48,7 @@ split(N, [Char|Tail], Acc) when is_integer(Char) -> split(N, [List|Tail], Acc0) -> case split(N, List, Acc0) of {ok, Before, After} -> - IolistSize = iolist_size(Before), - if - IolistSize < N -> - split(N - IolistSize, [After|Tail], lists:reverse(Before)); - true -> - {ok, Before, [After|Tail]} - end; + {ok, Before, [After|Tail]}; {more, More, Acc} -> split(More, Tail, Acc) end. @@ -72,7 +66,8 @@ split_test_() -> {10, ["He", [<<"ll">>], $o, [["!"]]], "Hello!", ""}, {10, ["Hel"|<<"lo!">>], "Hello!", ""}, {10, [[<<>>|<<>>], [], <<"Hello world!">>], "Hello worl", "d!"}, - {10, [[<<"He">>|<<"llo">>], [$\s], <<"world!">>], "Hello worl", "d!"} + {10, [[<<"He">>|<<"llo">>], [$\s], <<"world!">>], "Hello worl", "d!"}, + {10, [[[]|<<"He">>], [[]|<<"llo wor">>]|<<"ld!">>], "Hello worl", "d!"} ], [{iolist_to_binary(V), fun() -> {B, A} = split(N, V), -- cgit v1.2.3