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

Olabusayo Kilo updated DAFFODIL-3094:
-------------------------------------
    Summary: Failure when prefix separator is not backtracked after repeating 
complex element stops  (was: Failure when prefix separator is not backtracked 
after repeating complex element ends)

> Failure when prefix separator is not backtracked after repeating complex 
> element stops
> --------------------------------------------------------------------------------------
>
>                 Key: DAFFODIL-3094
>                 URL: https://issues.apache.org/jira/browse/DAFFODIL-3094
>             Project: Daffodil
>          Issue Type: Bug
>    Affects Versions: 4.2.0
>            Reporter: Olabusayo Kilo
>            Priority: Major
>             Fix For: 4.3.0
>
>         Attachments: data.dat, test.xsd
>
>
> Schema:
> {code:xml}
>   <xs:element name="r">
>     <xs:complexType>
>       <xs:sequence dfdl:separatorPosition="prefix" dfdl:separator="/ %NL;/" 
> dfdl:terminator="%NL;">
>         <xs:element name="foo" type="xs:string"/>
>         <xs:element name="GroupOfFields" maxOccurs="5" 
> dfdl:occursCountKind="implicit">
>           <xs:complexType>
>             <xs:sequence dfdl:separator="/ %NL;/" 
> dfdl:separatorSuppressionPolicy="never">
>               <xs:element name="c">
>                 <xs:complexType>
>                   <xs:choice>
>                     <xs:element name="bar" type="xs:string" 
> dfdl:initiator="R:"/>
>                     <xs:element name="ban" type="xs:string" 
> dfdl:initiator="N:"/>
>                   </xs:choice>
>                 </xs:complexType>
>               </xs:element>
>             </xs:sequence>
>           </xs:complexType>
>         </xs:element>
>         <xs:element name="baz" type="xs:string" minOccurs="0" />
>       </xs:sequence>
>     </xs:complexType>
>   </xs:element>
> {code}
> Data:
> {code:none}
> /1/N:ABC/R:DEF/N:HIJ/R:LMN/2
> {code}
> In the above, an outer sequence is separatorPosition="prefix" and a complex 
> element, GroupOfFields, has occursCountKind="implicit", minOccurs=1 and 
> maxOccurs=5, and the data has exactly 4 real GroupOfFields occurrences 
> (ABC/DEF/HIJ/LMN) followed by /2; that trailing / belongs to baz's own prefix 
> separator, and 2 is baz's value. 
>  
> Bug: since maxOccurs=5 and only 4 occurred, the parser must speculatively 
> attempt occurrence #5 (position 5 = maxRepeats, so 
> RequiredOptionalStatus.Optional). It: 
>   1. Parses the prefix separator / before slot 5 and succeeds (bits 208→216). 
>   2. Tries the child (GroupOfFields's inner choice bar/ban) and both 
> initiators fail, 0 bits consumed (isZL=true). 
>  
> That failure goes through anyTypeElementFailedParseAttemptStatus 
> (SequenceChildParseResultHelper.scala:190-218):
> {code:scala}
> case _: RequiredOptionalStatus.Optional if isZL => 
> ParseAttemptStatus.AbsentRep 
> {code}
> AbsentRep is documented as "backtrack any elements created but retain bit 
> position" which is exactly what parseOneInstanceWithMaybePoU does 
> (SequenceParserBases.scala:413-421): it resets to the PoU (undoing the 
> infoset side effects) but then explicitly forces the bit position back 
> forward past the separator (pstate.dataInputStream.setBitPos0b(currentPos)), 
> i.e. it keeps the separator consumed. 
>  
> That convention is correct for a simple type whose legitimate empty 
> representation is genuinely zero-length (classic "two adjacent separators = 
> an empty positional slot" idiom). But here the child is a complex type 
> wrapping a mandatory xs:choice with two required initiators; there is no such 
> thing as a valid zero-length match for it. The ZL failure isn't "the slot is 
> legitimately empty," it's "there is no occurrence 5 at all." Keeping the 
> separator steals the / that rightfully belongs to baz's own prefix separator, 
> so baz's separator search then fails, and ultimately the sequence terminator 
> search fails too. 
> anyTypeElementFailedParseAttemptStatus conflates two different situations 
> under one AbsentRep result: "legitimately empty content" vs. "total 
> structural failure with nothing consumed"; only the former should retain the 
> separator. The complex-type/model-group path currently has no static "can 
> this ever legitimately be zero-length" flag analogous to isEmptyRepZeroLength 
> (which simple types have) or isModelGroupRepPossiblyZeroLength (which exists 
> for model groups used directly as sequence children, but isn't threaded into 
> element-with-complex-type result helpers). 
>  
> This is a real design gap the code needs a way to know, for a complex-typed 
> array element, whether its content can ever be validly zero-length, and use 
> that to decide AbsentRep (retain separator) vs. a status that forces full 
> backtrack (give the separator back). 



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

Reply via email to