From f23a47e365028b7e9a4598125ed71ec00bdb1633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Chojnowski?= Date: Fri, 2 Apr 2021 14:21:15 +0200 Subject: [PATCH] utils: fragment_range: fix FragmentedView utils for views with empty fragments The copying and comparing utilities for FragmentedView are not prepared to deal with empty fragments in non-empty views, and will fall into an infinite loop in such case. But data coming in result_row_view can contain such fragments, so we need to fix that. Fixes #8398. Closes #8397 --- utils/fragment_range.hh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/utils/fragment_range.hh b/utils/fragment_range.hh index 95172a7814..3c752a7781 100644 --- a/utils/fragment_range.hh +++ b/utils/fragment_range.hh @@ -278,6 +278,13 @@ decltype(auto) with_simplified(const View& v, Function&& fn) } } +template +void skip_empty_fragments(View& v) { + while (!v.empty() && v.current_fragment().empty()) { + v.remove_current(); + } +} + template int compare_unsigned(V1 v1, V2 v2) { while (!v1.empty() && !v2.empty()) { @@ -287,6 +294,8 @@ int compare_unsigned(V1 v1, V2 v2) { } v1.remove_prefix(n); v2.remove_prefix(n); + skip_empty_fragments(v1); + skip_empty_fragments(v2); } return v1.size_bytes() - v2.size_bytes(); } @@ -306,6 +315,8 @@ void write_fragmented(Dest& dest, Src src) { memcpy(dest.current_fragment().data(), src.current_fragment().data(), n); dest.remove_prefix(n); src.remove_prefix(n); + skip_empty_fragments(dest); + skip_empty_fragments(src); } } @@ -319,6 +330,8 @@ void copy_fragmented_view(Dest dest, Src src) { memcpy(dest.current_fragment().data(), src.current_fragment().data(), n); dest.remove_prefix(n); src.remove_prefix(n); + skip_empty_fragments(dest); + skip_empty_fragments(src); } }