[
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)