summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2024-11-18 19:16:03 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2024-11-18 19:23:01 +0100
commitdc980fb9ad9f8590a9d438c3f10ef98418e44934 (patch)
tree2a27905838842ed9b1d3944e51576e9c9109e741
parent963efeff8778afacef35f69c181d234e0a27d5d3 (diff)
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 <christian@heusel.eu>
-rw-r--r--apt-pkg/cachefilter-patterns.h18
1 files changed, 17 insertions, 1 deletions
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){};