[
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)