Skip to content

Commit d2192d5

Browse files
committed
Fixes for dealing with large BLOBs and TEXTs
Fix receiving frames larger than 2^24-1 (>16M): read the next packet when the length of the first packet is 0xffffff. https://dev.mysql.com/doc/internals/en/sending-more-than-16mbyte.html Fix reading length encoded integer larger than 2^24; integer is encoded in 8-bytes instead of 4-bytes from MySQL 3.23 and later. https://dev.mysql.com/doc/internals/en/integer.html#length-encoded-integer
1 parent d553b9d commit d2192d5

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/mysql_conn.erl

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
%%% vim: noet ts=8 sts=4 sw=4
12
%%%-------------------------------------------------------------------
23
%%% File : mysql_conn.erl
34
%%% Author : Fredrik Thulin <ft@it.su.se>
@@ -263,18 +264,28 @@ do_recv(LogFun, RecvPid, SeqNum) when is_function(LogFun);
263264
LogFun == undefined,
264265
SeqNum == undefined ->
265266
receive
266-
{mysql_recv, RecvPid, data, Packet, Num} ->
267+
{mysql_recv, RecvPid, data, Packet, Num} when size(Packet) == 16#ffffff ->
268+
do_recv_more(LogFun, RecvPid, Packet, Num);
269+
{mysql_recv, RecvPid, data, Packet, Num} ->
267270
{ok, Packet, Num};
268271
{mysql_recv, RecvPid, closed, _E} ->
269272
{error, io_lib:format("mysql_recv: socket was closed ~p", [_E])}
270273
end;
271274
do_recv(LogFun, RecvPid, SeqNum) when is_function(LogFun);
272275
LogFun == undefined,
273276
is_integer(SeqNum) ->
277+
do_recv_more(LogFun, RecvPid, <<>>, SeqNum).
278+
279+
do_recv_more(LogFun, RecvPid, Partial, SeqNum) when is_function(LogFun);
280+
LogFun == undefined,
281+
is_binary(Partial),
282+
is_integer(SeqNum) ->
274283
ResponseNum = SeqNum + 1,
275284
receive
276-
{mysql_recv, RecvPid, data, Packet, ResponseNum} ->
277-
{ok, Packet, ResponseNum};
285+
{mysql_recv, RecvPid, data, Packet, ResponseNum} when size(Packet) == 16#ffffff ->
286+
do_recv_more(LogFun, RecvPid, <<Partial/binary, Packet/binary>>, ResponseNum);
287+
{mysql_recv, RecvPid, data, Packet, ResponseNum} ->
288+
{ok, <<Partial/binary, Packet/binary>>, ResponseNum};
278289
{mysql_recv, RecvPid, closed, _E} ->
279290
{error, io_lib:format("mysql_recv: socket was closed ~p", [_E])}
280291
end.
@@ -832,7 +843,8 @@ get_lcb(<<252:8, Value:16/little, Rest/binary>>) ->
832843
{Value, Rest};
833844
get_lcb(<<253:8, Value:24/little, Rest/binary>>) ->
834845
{Value, Rest};
835-
get_lcb(<<254:8, Value:32/little, Rest/binary>>) ->
846+
% for MySQL 3.23 or later, after a 0xfe the length is 8 bytes long
847+
get_lcb(<<254:8, Value:64/little, Rest/binary>>) ->
836848
{Value, Rest};
837849
get_lcb(<<Value:8, Rest/binary>>) when Value < 251 ->
838850
{Value, Rest};

0 commit comments

Comments
 (0)