From f1f7a92b18fb71142586a938bc2129518335d052 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 30 Sep 2024 10:48:07 +0200 Subject: [PATCH] Fix potential nullptr dereference when comparing streams. Because we are operating on unsafe iterators, need to catch when one goes out of bounds. Closes #1875. --- .typos.toml | 2 ++ hilti/runtime/src/types/stream.cc | 8 +++++++- .../types/unit/synchronize-after-with-trim.spicy | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/spicy/types/unit/synchronize-after-with-trim.spicy diff --git a/.typos.toml b/.typos.toml index 4b97f7a04..b9a06e44c 100644 --- a/.typos.toml +++ b/.typos.toml @@ -5,3 +5,5 @@ inout = "inout" ocur = "ocur" bigsur = "Big Sur" Smoot = "Smoot" +ba = "ba" +Datas = "Datas" diff --git a/hilti/runtime/src/types/stream.cc b/hilti/runtime/src/types/stream.cc index 668094905..8c12b50fe 100644 --- a/hilti/runtime/src/types/stream.cc +++ b/hilti/runtime/src/types/stream.cc @@ -565,6 +565,9 @@ bool stream::View::operator==(const View& other) const { auto j = other.unsafeBegin(); while ( i != unsafeEnd() ) { + if ( ! i.chunk() || ! j.chunk() ) + return (i.chunk() == j.chunk() && i.offset() == j.offset()); // same out-of-bounds iterators + if ( i.chunk()->isGap() != j.chunk()->isGap() ) return false; @@ -586,6 +589,9 @@ bool stream::View::operator==(const Bytes& other) const { auto j = other.begin(); while ( i != unsafeEnd() ) { + if ( ! i.chunk() ) // out-of-bounds, cannot match + return false; + if ( *i++ != *j++ ) return false; } @@ -594,7 +600,7 @@ bool stream::View::operator==(const Bytes& other) const { } std::string hilti::rt::detail::adl::to_string(const stream::SafeConstIterator& x, adl::tag /*unused*/) { - auto str = [](auto x) { + auto str = [](const auto& x) { auto y = x + 10; auto v = stream::View(x, y); if ( y.isEnd() ) diff --git a/tests/spicy/types/unit/synchronize-after-with-trim.spicy b/tests/spicy/types/unit/synchronize-after-with-trim.spicy new file mode 100644 index 000000000..9401c9918 --- /dev/null +++ b/tests/spicy/types/unit/synchronize-after-with-trim.spicy @@ -0,0 +1,14 @@ +# @TEST-EXEC: printf ba | spicy-driver -d %INPUT +# +# @TEST-DOC: Tests `%synchronize-after` with a fully trimmed view; regression test for #1875. + +module RESP; + +public type Datas = unit { + : (Data &synchronize)[] { confirm; } +}; + +type Data = unit { + %synchronize-after=b"a"; + ty: uint8 &requires=($$ < 5); + };