This is an automated email from the ASF dual-hosted git repository.

maskit 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 5c3352eb5b xpack: Fix division by zero error (#11107)
5c3352eb5b is described below

commit 5c3352eb5bbc3f11a11bff663b3befa956cf7ddb
Author: Masakazu Kitajo <mas...@apache.org>
AuthorDate: Wed Feb 28 11:21:06 2024 -0700

    xpack: Fix division by zero error (#11107)
    
    * xpack: Fix division by zero error
    
    * Simplify a formula
---
 include/proxy/hdrs/XPACK.h              |  5 +++++
 src/proxy/hdrs/XPACK.cc                 | 32 +++++++++++++++++++++-----------
 src/proxy/hdrs/unit_tests/test_XPACK.cc | 13 +++++++++++++
 3 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/include/proxy/hdrs/XPACK.h b/include/proxy/hdrs/XPACK.h
index f4b705a761..99829fe0cb 100644
--- a/include/proxy/hdrs/XPACK.h
+++ b/include/proxy/hdrs/XPACK.h
@@ -112,4 +112,9 @@ private:
    * Passing a value more than UINT32_MAX evicts every entry and return false.
    */
   bool _make_space(uint64_t required_size);
+
+  /**
+   * Calcurates the index number for _entries, which is a kind of circular 
buffer.
+   */
+  uint32_t _calc_index(uint32_t base, int64_t offset) const;
 };
diff --git a/src/proxy/hdrs/XPACK.cc b/src/proxy/hdrs/XPACK.cc
index e5eb070bd5..ca7d39e425 100644
--- a/src/proxy/hdrs/XPACK.cc
+++ b/src/proxy/hdrs/XPACK.cc
@@ -245,12 +245,12 @@ XpackDynamicTable::lookup(uint32_t index, const char 
**name, size_t *name_len, c
     return {0, XpackLookupResult::MatchType::NONE};
   }
 
-  if (index < this->_entries[(this->_entries_tail + 1) % 
this->_max_entries].index) {
+  if (index < this->_entries[this->_calc_index(this->_entries_tail, 1)].index) 
{
     // The index is invalid
     return {0, XpackLookupResult::MatchType::NONE};
   }
 
-  uint32_t pos = (this->_entries_head - 
(this->_entries[this->_entries_head].index - index)) % this->_max_entries;
+  uint32_t pos = this->_calc_index(this->_entries_head, index - 
this->_entries[this->_entries_head].index);
   *name_len    = this->_entries[pos].name_len;
   *value_len   = this->_entries[pos].value_len;
   this->_storage.read(this->_entries[pos].offset, name, *name_len, value, 
*value_len);
@@ -265,8 +265,8 @@ XpackDynamicTable::lookup(const char *name, size_t 
name_len, const char *value,
 {
   XPACKDebug("Lookup entry: name=%.*s, value=%.*s", 
static_cast<int>(name_len), name, static_cast<int>(value_len), value);
   XpackLookupResult::MatchType match_type = XpackLookupResult::MatchType::NONE;
-  uint32_t i                              = (this->_entries_tail + 1) % 
this->_max_entries;
-  uint32_t end                            = (this->_entries_head + 1) % 
this->_max_entries;
+  uint32_t i                              = 
this->_calc_index(this->_entries_tail, 1);
+  uint32_t end                            = 
this->_calc_index(this->_entries_head, 1);
   uint32_t candidate_index                = 0;
   const char *tmp_name                    = nullptr;
   const char *tmp_value                   = nullptr;
@@ -276,7 +276,7 @@ XpackDynamicTable::lookup(const char *name, size_t 
name_len, const char *value,
     return {candidate_index, match_type};
   }
 
-  for (; i != end; i = (i + 1) % this->_max_entries) {
+  for (; i != end; i = this->_calc_index(i, 1)) {
     if (name_len != 0 && this->_entries[i].name_len == name_len) {
       this->_storage.read(this->_entries[i].offset, &tmp_name, 
this->_entries[i].name_len, &tmp_value, this->_entries[i].value_len);
       if (match(name, name_len, tmp_name, this->_entries[i].name_len)) {
@@ -345,7 +345,7 @@ XpackDynamicTable::insert_entry(const char *name, size_t 
name_len, const char *v
   // Insert
   const char *wks = nullptr;
   hdrtoken_tokenize(name, name_len, &wks);
-  this->_entries_head                 = (this->_entries_head + 1) % 
this->_max_entries;
+  this->_entries_head                 = this->_calc_index(this->_entries_head, 
1);
   this->_entries[this->_entries_head] = {
     this->_entries_inserted++,
     this->_storage.write(name, static_cast<uint32_t>(name_len), value, 
static_cast<uint32_t>(value_len)),
@@ -433,14 +433,14 @@ XpackDynamicTable::maximum_size() const
 void
 XpackDynamicTable::ref_entry(uint32_t index)
 {
-  uint32_t pos = (this->_entries_head + (index - 
this->_entries[this->_entries_head].index)) % this->_max_entries;
+  uint32_t pos = this->_calc_index(this->_entries_head, (index - 
this->_entries[this->_entries_head].index));
   ++this->_entries[pos].ref_count;
 }
 
 void
 XpackDynamicTable::unref_entry(uint32_t index)
 {
-  uint32_t pos = (this->_entries_head + (index - 
this->_entries[this->_entries_head].index)) % this->_max_entries;
+  uint32_t pos = this->_calc_index(this->_entries_head, (index - 
this->_entries[this->_entries_head].index));
   --this->_entries[pos].ref_count;
 }
 
@@ -474,7 +474,7 @@ bool
 XpackDynamicTable::_make_space(uint64_t required_size)
 {
   uint32_t freed = 0;
-  uint32_t tail  = (this->_entries_tail + 1) % this->_max_entries;
+  uint32_t tail  = this->_calc_index(this->_entries_tail, 1);
 
   while (required_size > freed) {
     if (this->_entries_head < tail) {
@@ -484,12 +484,12 @@ XpackDynamicTable::_make_space(uint64_t required_size)
       break;
     }
     freed += this->_entries[tail].name_len + this->_entries[tail].value_len + 
ADDITIONAL_32_BYTES;
-    tail   = (tail + 1) % this->_max_entries;
+    tail   = this->_calc_index(tail, 1);
   }
 
   // Evict
   if (freed > 0) {
-    XPACKDebug("Evict entries: from %u to %u", 
this->_entries[(this->_entries_tail + 1) % this->_max_entries].index,
+    XPACKDebug("Evict entries: from %u to %u", 
this->_entries[this->_calc_index(this->_entries_tail, 1)].index,
                this->_entries[tail - 1].index);
     this->_available    += freed;
     this->_entries_tail  = tail - 1;
@@ -499,6 +499,16 @@ XpackDynamicTable::_make_space(uint64_t required_size)
   return required_size <= this->_available;
 }
 
+uint32_t
+XpackDynamicTable::_calc_index(uint32_t base, int64_t offset) const
+{
+  if (unlikely(this->_max_entries == 0)) {
+    return base + offset;
+  } else {
+    return (base + offset) % this->_max_entries;
+  }
+}
+
 //
 // DynamicTableStorage
 //
diff --git a/src/proxy/hdrs/unit_tests/test_XPACK.cc 
b/src/proxy/hdrs/unit_tests/test_XPACK.cc
index 222289c2f3..bfcc2fae3e 100644
--- a/src/proxy/hdrs/unit_tests/test_XPACK.cc
+++ b/src/proxy/hdrs/unit_tests/test_XPACK.cc
@@ -126,6 +126,19 @@ TEST_CASE("XPACK_String", "[xpack]")
     }
   }
 
+  SECTION("Zero-size Dynamic Table")
+  {
+    XpackDynamicTable dt(0);
+    XpackLookupResult result;
+
+    REQUIRE(dt.size() == 0);
+    REQUIRE(dt.maximum_size() == 0);
+    REQUIRE(dt.is_empty());
+    REQUIRE(dt.count() == 0);
+    result = dt.lookup("", "");
+    REQUIRE(result.match_type == XpackLookupResult::MatchType::NONE);
+  }
+
   SECTION("Dynamic Table")
   {
     constexpr uint16_t MAX_SIZE = 128;

Reply via email to