Jens Geyer created THRIFT-6328:
----------------------------------
Summary: Smalltalk: generated recv methods read the message
envelope from the output protocol
Key: THRIFT-6328
URL: https://issues.apache.org/jira/browse/THRIFT-6328
Project: Thrift
Issue Type: Bug
Components: Compiler (General)
Reporter: Jens Geyer
Fix For: 0.26.0
h2. Problem
{{TClient}} keeps two protocols, {{iprot}} and {{oprot}}, and offers
{{inProtocol:}} and {{outProtocol:}} so that a client can read and write over
different ones.
The generated {{recv}} methods read from the wrong one.
{{generate_recv_method}} in
{{compiler/cpp/src/thrift/generate/t_st_generator.cc}} emits:
{code}
msg := oprot readMessageBegin.
self validateRemoteMessage: msg.
res := [ ... iprot readStructBegin ... ] value.
oprot readMessageEnd.
oprot transport flush.
{code}
The message envelope is read from {{oprot}} while the struct inside it is read
from {{iprot}}, in the same method.
h2. Why it usually works
{{TClient>>inProtocol:}} is
{code}
inProtocol: aProtocol
iprot := aProtocol.
oprot ifNil: [oprot := aProtocol]
{code}
so a client built the usual way has {{oprot}} and {{iprot}} pointing at the
same object, and reading the envelope from either is the same thing.
A client that calls {{outProtocol:}} with a different protocol - which is the
only reason that setter exists - reads the envelope from the protocol it writes
to, and the body from the one the peer is answering on. It cannot work.
h2. Fix
Read with {{iprot}}. The flush belongs on the write side and stays on {{oprot}}.
THRIFT-6062 fixed the mirror image of this on the write side: {{write_val}}
emitted {{iprot write...}} for base types and enums while the rest of the write
path used {{oprot}}.
_Drafted with AI assistance (Claude Opus 5); reviewed and posted by Jens Geyer._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)