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)

Reply via email to