Copilot commented on code in PR #13621:
URL: https://github.com/apache/trafficserver/pull/13621#discussion_r3917700271


##########
src/proxy/http3/QPACK.cc:
##########
@@ -1155,7 +1155,13 @@ QPACK::_on_encoder_stream_read_ready(IOBufferReader 
&reader)
       }
       QPACKDebug("Received Insert With Name Ref: is_static=%d, index=%d, 
value=%.*s", is_static, index, static_cast<int>(value_len),
                  value);
-      StaticTable::lookup(index, &name, &name_len, &dummy, &dummy_len);
+      auto result = is_static ? StaticTable::lookup(index, &name, &name_len, 
&dummy, &dummy_len) :
+                                this->_dynamic_table.lookup(index, &name, 
&name_len, &dummy, &dummy_len);
+      if (result.match_type != XpackLookupResult::MatchType::EXACT) {
+        this->_arena.str_free(value);
+        this->_abort_decode();
+        return EVENT_DONE;
+      }

Review Comment:
   On Insert With Name Reference, a failed name lookup now aborts decoding, but 
there is no test exercising this encoder-stream failure path (e.g. 
dynamic-table name ref that is out of range / not present). Adding a focused 
unit test would prevent regressions and ensure the new abort behavior is 
observable.



##########
src/proxy/http3/QPACK.cc:
##########
@@ -1221,6 +1227,10 @@ QPACK::estimate_header_block_size(const HTTPHdr & /* hdr 
ATS_UNUSED */)
 const XpackLookupResult
 QPACK::StaticTable::lookup(uint16_t index, const char **name, size_t 
*name_len, const char **value, size_t *value_len)
 {
+  if (index >= countof(STATIC_HEADER_FIELDS)) {
+    return {index, XpackLookupResult::MatchType::NONE};
+  }
+

Review Comment:
   StaticTable::lookup now guards against out-of-range indexes, but the API 
takes a uint16_t index. Call sites decode the peer-supplied index into a 
uint64_t (e.g. _decode_indexed_header_field() around QPACK.cc:696-717) and then 
implicitly narrow it when calling lookup(), which means values > 0xFFFF can 
wrap into a small in-range number and bypass the bounds check. Additionally, 
_read_insert_with_name_ref() currently assigns a decoded uint64_t to a uint16_t 
(QPACK.cc:1526-1531), so the same wraparound risk exists on the encoder stream 
path. Consider changing the lookup/index plumbing to use a wider integer type 
(uint64_t/size_t) and explicitly reject values >= countof(STATIC_HEADER_FIELDS) 
before any narrowing.



##########
src/proxy/http3/test/test_QPACK.cc:
##########
@@ -405,6 +405,31 @@ test_decode(const char *enc_file, const char *out_file, 
int dts, int mbs)
   return ret;
 }
 
+TEST_CASE("Decoding out-of-range static table indexes fails", "[qpack-decode]")
+{
+  QUICApplicationDriver driver;
+  QPACK                 qpack(driver.get_connection(), UINT32_MAX, 0, 0, 
MAX_FIELD_SIZE);
+  TestQPACKEventHandler event_handler;
+  HTTPHdr               hdr;
+
+  hdr.create(HTTPType::REQUEST);
+
+  const uint8_t header_block[] = {
+    0x00, // Required Insert Count.
+    0x00, // Delta Base.
+    0xff, // Indexed static field with an extended 6-bit index.
+    0x25, // Index 100.
+  };
+
+  CHECK(qpack.decode(1, header_block, sizeof(header_block), hdr, 
&event_handler, eventProcessor.all_ethreads[0]) == 0);
+
+  sleep(1);
+
+  CHECK(event_handler.last_event() == QPACK_EVENT_DECODE_FAILED);

Review Comment:
   The new test adds another unconditional sleep(1), which makes the unit test 
suite slower and can still be flaky on slow/loaded systems. Prefer polling for 
the event with a bounded timeout so the test completes quickly when the event 
arrives promptly and still fails deterministically if it never arrives.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to