This is an automated email from the ASF dual-hosted git repository.
bneradt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 50c7470e5a XPACK: Inspect _start_expanding_capacity before expanding
(#12228)
50c7470e5a is described below
commit 50c7470e5ab05f050b283cecbd76b4db54fdc41e
Author: Brian Neradt <[email protected]>
AuthorDate: Wed May 7 16:18:16 2025 -0500
XPACK: Inspect _start_expanding_capacity before expanding (#12228)
While expanding XPACK storage, crashes were happening with _old_data
being nullptr. This will likely be fixed by checking the result of
_start_expanding_capacity before trying to expand capacity.
Fixes: #12225
---
include/proxy/hdrs/XPACK.h | 15 ++++++++++++++-
src/proxy/hdrs/XPACK.cc | 7 +++++--
src/proxy/hdrs/unit_tests/test_XPACK.cc | 7 +++++++
3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/include/proxy/hdrs/XPACK.h b/include/proxy/hdrs/XPACK.h
index da41b069f9..8a6cd1011c 100644
--- a/include/proxy/hdrs/XPACK.h
+++ b/include/proxy/hdrs/XPACK.h
@@ -165,7 +165,7 @@ public:
/** Begin the storage expansion phase to the @a new_max_size. */
ExpandCapacityContext(XpackDynamicTableStorage &storage, uint32_t
new_max_size) : _storage{storage}
{
- this->_storage._start_expanding_capacity(new_max_size);
+ this->_ok_to_expand =
this->_storage._start_expanding_capacity(new_max_size);
}
/** End the storage expansion phase, cleaning up the old storage memory. */
~ExpandCapacityContext() { this->_storage._finish_expanding_capacity(); }
@@ -183,8 +183,21 @@ public:
*/
uint32_t copy_field(uint32_t old_offset, uint32_t len);
+ /** Indicate whether the expansion should proceed.
+ * Return whether @a _storage indicates that the new max size is valid for
+ * expanding the storage. If not, the expansion should not proceed.
+ *
+ * @return true if the new size is valid, false otherwise.
+ */
+ bool
+ ok_to_expand() const
+ {
+ return this->_ok_to_expand;
+ }
+
private:
XpackDynamicTableStorage &_storage;
+ bool _ok_to_expand = false;
};
class XpackDynamicTable
diff --git a/src/proxy/hdrs/XPACK.cc b/src/proxy/hdrs/XPACK.cc
index 6898a36fa9..6d0cde9643 100644
--- a/src/proxy/hdrs/XPACK.cc
+++ b/src/proxy/hdrs/XPACK.cc
@@ -485,8 +485,11 @@ void
XpackDynamicTable::_expand_storage_size(uint32_t new_storage_size)
{
ExpandCapacityContext context{this->_storage, new_storage_size};
- uint32_t i = this->_calc_index(this->_entries_tail, 1);
- uint32_t end = this->_calc_index(this->_entries_head, 1);
+ if (!context.ok_to_expand()) {
+ return;
+ }
+ uint32_t i = this->_calc_index(this->_entries_tail, 1);
+ uint32_t end = this->_calc_index(this->_entries_head, 1);
for (; i != end; i = this->_calc_index(i, 1)) {
auto &entry = this->_entries[i];
entry.offset = context.copy_field(entry.offset, entry.name_len +
entry.value_len);
diff --git a/src/proxy/hdrs/unit_tests/test_XPACK.cc
b/src/proxy/hdrs/unit_tests/test_XPACK.cc
index a0eace5a5f..a7f3da0e92 100644
--- a/src/proxy/hdrs/unit_tests/test_XPACK.cc
+++ b/src/proxy/hdrs/unit_tests/test_XPACK.cc
@@ -460,6 +460,7 @@ TEST_CASE("XpackDynamicTableStorage", "[xpack]")
uint32_t reoffset2 = 0, reoffset3 = 0, reoffset4 = 0;
{
ExpandCapacityContext context{storage, 200};
+ REQUIRE(context.ok_to_expand());
reoffset2 = context.copy_field(offset2, 50);
// Note that the offsets will now be shifted, starting from 0 now.
REQUIRE(reoffset2 == 0);
@@ -478,4 +479,10 @@ TEST_CASE("XpackDynamicTableStorage", "[xpack]")
storage.read(reoffset4, &name, 25, &value, 25);
REQUIRE(memcmp(name, name4.data(), 25) == 0);
REQUIRE(memcmp(value, value4.data(), 25) == 0);
+
+ // Test shrinking capacity. This should be rejected via ok_to_expand().
+ {
+ ExpandCapacityContext context{storage, 0};
+ REQUIRE(!context.ok_to_expand());
+ } // context goes out of scope and finishes the expansion phase.
}