Client: cpp
An odr-used static const data member needs this out-of-line definition in
every C++ standard; drop it only once the constants become inline
constexpr.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Client: cpp
A THeader frame applies each transform it lists in turn, so the work one
frame can request grows with the number of transforms rather than with its
declared size. A valid frame never lists more than one, so refuse a larger
count when the header is parsed, before the transform list is built.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
TFramedTransport has three constructors. The two that take an underlying
transport initialise maxFrameSize_ from the configuration; the one that takes
only a TConfiguration leaves it out of its member-init list, so
getMaxFrameSize() reads an uninitialised member and the frame-size limit it
reports is whatever happened to be on the stack. Observed values in the added
test were 0 and 21988 against a configured 4096.
Nothing in the tree uses that constructor, so this is only reachable from
outside the library, and a transport built that way has no underlying transport
to read from until one is set. It is still an uninitialised read of a member
that decides a size limit.
The test states the contract -- all three constructors agree with the
configuration -- rather than claiming to detect the defect reliably: reading an
indeterminate value is undefined, so a run that happened to find the right bytes
there would pass.
Client: cpp
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Client: cpp
Bind THeaderTransport::readFrame() to TConfiguration::maxFrameSize the same
way TFramedTransport::readFrame() already does, and apply that same limit to
the post-transform (decompressed) payload, so the header transport honours the
operator-configured frame-size limit consistently rather than only the
internal MAX_FRAME_SIZE ceiling.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Client: cpp
TFramedTransportFactory, THeaderTransportFactory, TBufferedTransportFactory,
TPipedTransportFactory, TPipedFileReaderTransportFactory, TZlibTransportFactory,
and THttpServerTransportFactory (base of both TWebSocketServer variants) all
constructed their wrapper transport without forwarding the TConfiguration
already attached to the transport being wrapped, so the wrapper picked up a
fresh default TConfiguration instead of the caller's. This diverges from
doc/specs/thrift-tconfiguration.md, which documents that every layer of the
transport/protocol stack should share one TConfiguration instance by
reference. Each factory now passes the wrapped transport's configuration
through to its wrapper's constructor.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>