From dc980fb9ad9f8590a9d438c3f10ef98418e44934 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 18 Nov 2024 19:16:03 +0100 Subject: patterns: Safely peek ahead one byte The pattern tree parser was written using string_views in a no-copy fashion. However, at various places we assume that we can index one byte after the end of the string_view and get a NUL-byte there. This works fine in practice because we only ever pass it zero-terminated string_views, but it fails if you compile with -Wp,-D_GLIBCXX_ASSERTIONS because it will do bounds checks. So instead, do our own bounds checks here and always return '\0' if requesting one byte too many. Reported-by: Christian Heusel --- apt-pkg/cachefilter-patterns.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/apt-pkg/cachefilter-patterns.h b/apt-pkg/cachefilter-patterns.h index a45b9afcf..75784e040 100644 --- a/apt-pkg/cachefilter-patterns.h +++ b/apt-pkg/cachefilter-patterns.h @@ -78,7 +78,23 @@ struct APT_PUBLIC PatternTreeParser size_t offset = 0; }; - std::string_view sentence; + /// \brief Zero-terminated wrapper for std::string_view + /// + /// The code peeks a character ahead and assumes the input is zero-terminated, but it may not be, + /// this class provides a peek-ahead character access in operator[] by returning 0 for [size()]. + struct ZeroStringView : private std::string_view + { + explicit ZeroStringView(std::string_view s) : std::string_view(s) {} + char operator[](size_t i) + { + assert(i <= size()); + if (likely(i < size())) + return std::string_view::operator[](i); + return '\0'; + } + using std::string_view::size; + using std::string_view::substr; + } sentence; State state; PatternTreeParser(std::string_view sentence) : sentence(sentence){}; -- cgit v1.2.3-70-g09d2