[ 
https://issues.apache.org/jira/browse/THRIFT-6300?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jens Geyer resolved THRIFT-6300.
--------------------------------
    Fix Version/s: 0.26.0
         Assignee: Jens Geyer
       Resolution: Fixed

> Smalltalk: TBinaryProtocol decodes what the transport returned without 
> checking its length
> ------------------------------------------------------------------------------------------
>
>                 Key: THRIFT-6300
>                 URL: https://issues.apache.org/jira/browse/THRIFT-6300
>             Project: Thrift
>          Issue Type: Bug
>          Components: Smalltalk - Library
>            Reporter: Jens Geyer
>            Assignee: Jens Geyer
>            Priority: Minor
>             Fix For: 0.26.0
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> {{TTransport}} has a read-exactly method that loops until it has the bytes it 
> was asked for ({{lib/st/thrift.st:790}}):
> {code}
> readAll: anInteger
>       ^ String streamContents: [:str |
>               [str size < anInteger] whileTrue:
>                       [str nextPutAll: (self read: anInteger - str size)]]
> {code}
> {{TBinaryProtocol}} never calls it. {{readInt:}} ({{:254}}), {{readRawInt:}} 
> ({{:298}}) and {{readString}} ({{:312}}) each take whatever one {{transport 
> read:}} returns and decode that:
> {code}
> readInt: size
>       | buf val |
>       buf := transport read: size.
>       val := self intFromByteArray: buf.
>       ^ buf first > 16r7F
>               ifTrue: [self unsignedInt: val size: size]
>               ifFalse: [val]
> {code}
> {{TSocket>>read:}} ({{:730}}) raises only when the result {{isEmpty}}, so a 
> short but non-empty result is passed straight through. {{intFromByteArray:}} 
> ({{:210}}) then takes its width from {{buf size}} rather than from {{size}}, 
> so two bytes delivered for an {{i32}} produce a well-formed but wrong integer 
> instead of an error, and {{buf first}} takes the sign from the wrong byte. 
> {{readString}} checks the *declared* size against the string limit but not 
> how many bytes actually arrived, so it can return a truncated string as if it 
> were complete.
> {{lib/st}} ships no server transport, so this needs a peer that answers and 
> then truncates the response.
> h2. Suggested
> Use {{readAll:}} in all three places. It already exists and already has the 
> loop; nothing new has to be written.
> A caveat on verification: the binding cannot be built or run in the usual 
> environments, so whether a given dialect's {{SocketStream>>next:}} actually 
> yields a short non-empty result on a truncated peer response has not been 
> observed, only read. Confirming it needs Pharo.
> _Drafted with AI assistance (Claude Opus 5); reviewed and filed by Jens 
> Geyer._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to