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

Jens Geyer resolved THRIFT-6279.
--------------------------------
    Fix Version/s: 0.25.0
         Assignee: Jens Geyer
       Resolution: Fixed

> Erlang: the JSON protocol cannot read a message and writes binary strings 
> unquoted
> ----------------------------------------------------------------------------------
>
>                 Key: THRIFT-6279
>                 URL: https://issues.apache.org/jira/browse/THRIFT-6279
>             Project: Thrift
>          Issue Type: Bug
>          Components: Erlang - Library
>            Reporter: Jens Geyer
>            Assignee: Jens Geyer
>            Priority: Major
>             Fix For: 0.25.0
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> Found while working on THRIFT-6269. {{thrift_json_protocol}} does not 
> round-trip a message. The Erlang cross test covers only binary and compact, 
> and {{lib/erl/test}} has no JSON test, so nothing notices. Measured on master 
> with OTP 25 and 28.
> h2. 1. Reading any message fails
> {{convert_data(integer, I)}} calls {{list_to_integer(I)}}. That dates from 
> THRIFT-1227, when the protocol used jsx. THRIFT-1357 (2014) replaced jsx with 
> {{thrift_json_parser}}, whose {{format_number/1}} already returns integers. 
> Since then {{list_to_integer/1}} is handed an integer.
> * A message the protocol wrote itself fails to read at its version number 
> with {{badarg}}.
> * The integer clause of {{read(_, byte)}} has the same call.
> h2. 2. A string given as a binary is written without quotes
> The generator's default {{string=both}} accepts a string field as a binary, 
> but {{write(_, \{string, Str\})}} writes a binary unchanged.
> * Measured: the field comes out as {{"str":abc}}, which is not JSON.
> * A string given as a list is quoted, but nothing in it is escaped.
> h2. 3. Over a socket the read never ends
> {{read_all/1}} reads until the transport returns nothing more, which a socket 
> or framed transport never does: it waits for more data.
> Measured with {{thrift_socket_server}} and {{thrift_client_util}} using the 
> JSON protocol, both buffered and framed:
> * The server process dies at its 500 ms receive timeout with a 
> {{case_clause}} on {{\{error,timeout\}}}.
> * The client call returns an error with {{case_clause}} on 
> {{\{error,closed\}}}.
> * The binary protocol works in the same setup.
> h2. 4. One transport call per byte
> {{read_all_1/2}} asks the transport for one byte at a time. This is the 
> second point of THRIFT-6269, left out of PR #3867 because of 1 to 3.
> h2. Suggested
> * Fix 1 and 2, with round-trip tests over a memory buffer. For the list case, 
> the test should include characters that need escaping.
> * Make the read end with the message, not with the stream: parse 
> incrementally, or read what the parser still needs.
> * Then read in larger pieces, and resolve the {{\{error, 'EOF'\}}} clause in 
> {{read_all_1/2}}. Its only producer, {{thrift_http_transport:read/2}}, cannot 
> reach it.
> * Add JSON to the Erlang entry of {{test/tests.json}} once it works.
> _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