Olabusayo Kilo created DAFFODIL-3094:
----------------------------------------

             Summary: Failure when prefix separator is not backtracked after 
repeating complex element ends
                 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
             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