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

Ramin Gharib updated FLINK-41204:
---------------------------------
    Priority: Minor  (was: Major)

> VARIANT JSON parsing replaces unpaired surrogates with '?' instead of failing
> -----------------------------------------------------------------------------
>
>                 Key: FLINK-41204
>                 URL: https://issues.apache.org/jira/browse/FLINK-41204
>             Project: Flink
>          Issue Type: Bug
>          Components: API / Core
>            Reporter: Ramin Gharib
>            Assignee: Ramin Gharib
>            Priority: Minor
>
> A JSON string can hold an escaped surrogate without its pair, such as U+D800 
> on its own. That is not valid Unicode, so it has no UTF-8 encoding, see RFC 
> 8259 section 7. The VARIANT builder encodes text with 
> {{String.getBytes(UTF_8)}}, which writes {{?}} in place of the surrogate. The 
> VARIANT then holds different text than the input, and nothing fails.
> Two inputs show it:
> {noformat}
> 1. {"a\ud800": 1}      lone surrogate in a key
> 2. {"a": "x\ud800"}    lone surrogate in a string value
> {noformat}
> Whether Flink rejects them depends on the entry point:
> ||Entry point||Parser input||Input 1||Input 2||
> |{{PARSE_JSON}}, {{TRY_PARSE_JSON}}|bytes|fails|value stored as {{x?}}|
> |{{json}} format, VARIANT column|bytes for the record, then a {{String}} per 
> VARIANT|fails|value stored as {{x?}}|
> |{{raw}} format, VARIANT|{{String}}|key stored as {{a?}}|value stored as 
> {{x?}}|
> Jackson's byte parser checks surrogate pairs in field names, but not in 
> string values. Its {{String}} parser checks neither. The table comes from the 
> parser calls each entry point makes, with the shaded Jackson 2.22.2 on master.
> *Proposal*
> Reject unpaired surrogates in {{BinaryVariantInternalBuilder.buildJson}}, in 
> keys and in string values, before they are encoded. All entry points then 
> agree: {{PARSE_JSON}} fails, {{TRY_PARSE_JSON}} returns NULL, and the 
> {{json}} and {{raw}} formats report a deserialization error.
> Spark made the same change in SPARK-56654 for Spark 4.3.0. It rejects lone 
> surrogates in keys and string values when parsing JSON into a variant: 
> {{parse_json}} fails and {{try_parse_json}} returns NULL. The check is on by 
> default, and the internal conf 
> {{spark.sql.variant.validateUnicodeInJsonParsing}} turns it off.
> *Open question*
> Rejecting turns input that parses today into an error. A source that reads 
> such records with the {{raw}} format then fails, and so does the {{json}} 
> format unless {{json.ignore-parse-errors}} skips them. Should Flink keep an 
> opt-out like Spark's?
> *Out of scope*
> {{BinaryVariantBuilder}} and {{Variant.getField}} keep encoding a lone 
> surrogate as {{?}}. {{StringData}} does the same, see 
> {{StringUtf8Utils.encodeUTF8}}.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to