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

Radu Cotescu updated SLING-13268:
---------------------------------
    Component/s: GraphQL

> PartialReader section slicing breaks when Reader.skip() returns 0
> -----------------------------------------------------------------
>
>                 Key: SLING-13268
>                 URL: https://issues.apache.org/jira/browse/SLING-13268
>             Project: Sling
>          Issue Type: Bug
>          Components: GraphQL
>            Reporter: Rishabh Daim
>            Assignee: Rishabh Daim
>            Priority: Major
>
> h3. Summary
> {{PartialReader}} builds a section's content by wrapping a reader with 
> commons-io's {{BoundedReader}} to stop at the section's end. Two independent 
> bugs in this path let one section's content run into the next one, leaking 
> raw {{QUERY:}}/{{TYPES:}} header lines into the aggregated SDL and breaking 
> GraphQL parsing downstream.
> h3. Root causes
> # *Unchecked {{skip()}} call* - the code called 
> {{reader.skip(startCharIndex)}} once and assumed it always fully advances. 
> {{Reader.skip()}} is allowed to skip fewer characters than requested per call.
> # *commons-io {{BoundedReader}} regression (2.22.0+)* - confirmed by 
> reproduction. {{BoundedReader}} was refactored to extend {{ProxyReader}} in 
> 2.22.0. It bounds {{read()}} and {{read(char[],int,int)}}, but *not* 
> {{read(char\[\])}} - that overload falls through to 
> {{ProxyReader.read(char[])}}, which delegates straight to the wrapped reader 
> with no bound check at all. {{IOUtils.copy(Reader, Writer)}}, used to copy 
> each section's content, reads through exactly that unbounded overload. 2.21.0 
> and earlier didn't have this problem since {{BoundedReader}} extended 
> {{java.io.Reader}} directly, whose default {{read()}}/{{read(char[])}} 
> correctly delegate to the bounded 3-arg method.
> This is why the aggregator worked fine through commons-io 2.21.0 and broke as 
> soon as a runtime picked up 2.22.0 - this project depends on commons-io as 
> {{provided}}, so the actual version is whatever the OSGi container resolves, 
> not what's pinned in this repo's pom.
> h3. Impact
> Reproduced against real production schema partials: with commons-io 2.22.0 on 
> the classpath, a {{TYPES:}} header line and the following section's content 
> leak into the previous section, and {{graphql-java}}'s {{SchemaParser}} fails 
> with {{SchemaProblem: token recognition error at: '--'}} - matching the 
> failure seen in {{GraphQLContentFragmentListIT}}.
> h3. Fix
> * Added {{skipFully()}}, looping (falling back to {{read()}}) until the 
> requested offset is reached or EOF.
> * Replaced commons-io's {{BoundedReader}} with a small self-contained 
> {{BoundedContentReader}} that extends {{java.io.Reader}} directly and only 
> overrides {{read(char[],int,int)}} - the JDK's own default 
> {{read()}}/{{read(char[])}} delegate to it, so every overload stays bounded 
> regardless of which commons-io version ends up on the runtime classpath.
> Verified byte-for-byte against the real production schema files with 
> commons-io 2.22.0 pinned: output now matches the known-good (2.21.0) baseline 
> exactly and parses successfully.



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

Reply via email to