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

Jens Geyer reassigned THRIFT-6161:
----------------------------------

    Assignee: Jens Geyer

> Haxe TStreamTransport does not charge reads against MaxMessageSize
> ------------------------------------------------------------------
>
>                 Key: THRIFT-6161
>                 URL: https://issues.apache.org/jira/browse/THRIFT-6161
>             Project: Thrift
>          Issue Type: Bug
>          Components: Haxe - Library
>            Reporter: Jens Geyer
>            Assignee: Jens Geyer
>            Priority: Major
>             Fix For: 0.25.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> h3. Problem
> {{TStreamTransport}} does not charge reads against the message budget, so 
> MaxMessageSize has
> no effect on a stream-backed connection however much a message reads, as long 
> as no single
> read exceeds the limit on its own. Its {{flush()}} does not restore the 
> allowance either.
> h3. Why this is a defect in Haxe specifically
> There is no single convention across the bindings — there are three, and 
> every other binding
> keeps to one of them:
> * *cpp, c_glib* — no endpoint charges reads (only the zlib transport does); 
> reads are bounded by frame binding and the per-read check alone.
> * *java, netstd* — stream and socket endpoints do not charge; endpoints that 
> know the message boundary do ({{THttpClient}} / {{THttpTransport}}, named 
> pipes, a memory buffer holding one message).
> * *delphi* — every endpoint charges.
> Haxe is the only binding that departs from its own convention. It has four 
> endpoint transports:
> {{TSocket}} charges (three sites), {{THttpClient}} charges, 
> {{TFullDuplexHttpClient}} charges,
> and {{TStreamTransport}} charges nothing. The binding's design intends 
> endpoints to charge, and
> this one silently opts out.
> {{doc/specs/thrift-tconfiguration.md}} describes MaxMessageSize as "a general 
> device to be used
> with any transport or protocol", expressed as the bytes *remaining* to be 
> read — which only
> means something if reads draw it down.
> h3. Fix
> Two coordinated changes, mirroring {{TSocket}}:
> * {{read()}} charges what it read.
> * {{flush()}} resets the allowance, at the same point {{TSocket}} does.
> Both are needed. Charging without resetting would leave the budget only ever 
> shrinking, so a
> long-lived connection would run itself out of it — which is THRIFT-6160, 
> fixed just before this.
> h3. Tests
> Two, in {{StreamTest}}, failing before and passing after. The first reads 
> past the limit 32 bytes
> at a time, so nothing but cumulative accounting can catch it; the second 
> checks the allowance comes
> back. Verified on neko (full suite, including the existing stream, constants 
> and recursion-limit
> tests, all of which read through {{TStreamTransport}}); the python and php 
> targets cross-compile
> clean.
> _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