From 124f5daa00ec753801f19ecef0af9eb92826a7ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Fri, 19 Sep 2025 15:56:58 +0200 Subject: [PATCH] CQ shared: Fix off-by-nine error leading to lost messages And `eof` crashes. The problem is that we may end up trying to read more data from the file when scanning, despite being at the end of the file. This results in the current Acc to be returned instead of the remaining data being parsed. This results in some messages at the end of the file being truncated off despite still being in memory (and still pointing to the end of the original file, well past the truncation point). (cherry picked from commit f36385408aa4b21f03c39bed5223ef630555db6b) --- deps/rabbit/src/rabbit_msg_store.erl | 2 +- deps/rabbit/test/backing_queue_SUITE.erl | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/deps/rabbit/src/rabbit_msg_store.erl b/deps/rabbit/src/rabbit_msg_store.erl index ea5e55be4c0a..f706f2f24334 100644 --- a/deps/rabbit/src/rabbit_msg_store.erl +++ b/deps/rabbit/src/rabbit_msg_store.erl @@ -1599,7 +1599,7 @@ scan_data(<> = Data, Fd, Fun, Offset, FileSiz end; %% This might be the start of a message. scan_data(<> = Data, Fd, Fun, Offset, FileSize, MsgIdsFound, Acc) - when byte_size(Rest) < Size + 1, Size < FileSize - Offset -> + when byte_size(Rest) < Size + 1, Size + 9 =< FileSize - Offset -> scan(Data, Fd, Fun, Offset, FileSize, MsgIdsFound, Acc); scan_data(Data, Fd, Fun, Offset, FileSize, MsgIdsFound, Acc) when byte_size(Data) < 8 -> diff --git a/deps/rabbit/test/backing_queue_SUITE.erl b/deps/rabbit/test/backing_queue_SUITE.erl index d7a7c526b4f9..01ff9f5aa259 100644 --- a/deps/rabbit/test/backing_queue_SUITE.erl +++ b/deps/rabbit/test/backing_queue_SUITE.erl @@ -710,6 +710,17 @@ msg_store_file_scan1(Config) -> [{bin, <<0, 0:48, 17, 17, "idididididididid", 255, 0:4352/unit:8, 255>>}], {ok, [{<<"idididididididid">>, 4378, 1}]}, fun(Obj = {<<"idididididididid">>, 4378, 1}) -> {valid, Obj}; (_) -> invalid end), + %% Off-by-nine regression testing. The file scanning could miss + %% some messages if previous data looked like a message but its + %% size went past the end of the file. + lists:foreach(fun(N) -> + ok = Scan([ + {bin, <<(4194304 + N):64, 0:(4194304 - 8 - 25 - 10)/unit:8>>}, + {msg, gen_id(), <<>>}, + %% Padding ensures there's no 255 at the end of the size indicated by 'bin'. + {pad, 10} + ]) + end, lists:seq(-9, -1)), %% All good!! passed.