brbzull0 commented on code in PR #13635:
URL: https://github.com/apache/trafficserver/pull/13635#discussion_r3956794193


##########
src/proxy/http3/Http3Transaction.cc:
##########
@@ -225,6 +225,13 @@ HQTransaction::transaction_done()
 
 int
 HQTransaction::get_transaction_id() const
+{
+  // Narrowing is intentional here; see get_quic_stream_id() for the 
full-width value.
+  return static_cast<int>(this->_stream_id);
+}

Review Comment:
   Copilot asked for this cast in its Sep 4 comment on this line — "make the 
truncation explicit to avoid accidental sign/width issues" — so I'd rather not 
churn it back on the same grounds.
   
   More to the point, ATS already relies on this conversion. `Http2StreamId` is 
`uint32_t`, `Http2Stream::_id` is initialized to `-1` (`Http2Stream.h:217`), 
and `Http2ConnectionState::set_stream_id()` uses `stream->get_transaction_id() 
< 0` as its unassigned sentinel (`Http2ConnectionState.cc:1704`). That works 
only because `uint32_t(0xFFFFFFFF)` narrows to `int(-1)`. HTTP/2 also does the 
same narrowing with no cast at all: `Http2Stream::get_transaction_id()` is 
`return _id;`.
   
   On the standard: `QUICStreamId` is `uint64_t`, and this file builds as core, 
where the standard is C++20. P1236R1 rewrote `[conv.integral]/3` on top of 
mandatory two's complement and deleted the signed/unsigned split, so the result 
is the unique destination-type value congruent to the source modulo 2^N — 
well-defined, not implementation-defined. It was implementation-defined in 
C++17, so the concern was fair for that standard. The one platform dependence 
left is the width of `int` itself, which the standard leaves 
implementation-defined with a 16-bit minimum; it's 32 everywhere ATS runs. Note 
that `static_cast<int>(static_cast<uint32_t>(x))` is bit-identical for any 
`int` narrower than 33 bits, and diverges from the direct cast only on a 
64-bit-`int` target — where the intermediate step is the one that loses the 
modular guarantee.
   
   The `int` return isn't ours to widen: 
`ProxyTransaction::get_transaction_id()` is pure virtual with that signature, 
and covariant return doesn't apply to scalars.
   
   A clamp or assert would change the behavior of a log field, and no 
`numeric_cast` helper exists in ATS or swoc to reach for. The first negative 
value appears at stream id 2^31; client bidi ids advance by 4, so that's 
roughly 2^29 — about 537 million streams on a single connection. After this PR 
nothing routes, indexes, or compares on this value; it feeds debug output 
(formatted `PRIx32`, so unsigned regardless) and the `ctid` log field. Leaving 
as-is.
   



-- 
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