Ramin Gharib created FLINK-40305:
------------------------------------

             Summary: VARIANT string and object key decoding ignores the UTF-8 
charset
                 Key: FLINK-40305
                 URL: https://issues.apache.org/jira/browse/FLINK-40305
             Project: Flink
          Issue Type: Bug
          Components: API / Core
            Reporter: Ramin Gharib
            Assignee: Ramin Gharib


{\{BinaryVariantUtil}} decodes variant strings and object field names without 
passing a charset, so both fall back to the JVM default:
 
{code:java}
// getString
return new String(value, start, length);
// getMetadataKey
return new String(metadata, stringStart + offset, nextOffset - offset);
{code}
 
Both are written as UTF-8 by \{{BinaryVariantInternalBuilder}}, which uses 
\{{str.getBytes(StandardCharsets.UTF_8)}} for values and 
\{{key.getBytes(StandardCharsets.UTF_8)}} for keys, so the write and read paths 
disagree.
 
The default charset is only guaranteed to be UTF-8 from Java 18 onwards (JEP 
400). On Java 11 and 17 it is platform dependent, so a variant holding 
non-ASCII text can decode incorrectly. \{{new String(byte[], ...)}} also 
substitutes \{{U+FFFD}} for malformed input rather than failing.
 
{\{getMetadataKey}} is the more damaging of the two, since it decodes field 
names. A mangled name makes \{{getField(name)}} silently return null and 
corrupts \{{getFieldNames()}} and \{{toJson()}}.
 
This is a regression from the original port. Spark's \{{VariantUtil}}, which 
this class is derived from, passes the charset in both places:
 
{code:java}
return new String(value, start, length, StandardCharsets.UTF_8);
return new String(metadata, stringStart + offset, nextOffset - offset, 
StandardCharsets.UTF_8);
{code}
 
h3. Fix
Pass \{{StandardCharsets.UTF_8}} in both calls. Add a round-trip test with a 
non-ASCII string value and a non-ASCII field name.



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

Reply via email to