The issue appears to be with how we don't really require fillByte until
runtime.

RuntimePropertyMixins.scala defines maybeFillByteEv, which returns the
FillByteEv if the dfdl:fillByte property is provided on the schema
element. If it's not provided, it's just a Nope and we don't have a fill
byte. So our code for creating FillByteEv implies that the dfdl:fillByte
property is not mandatory.

But then in ProcessorStateBases.scala, the def fillByte function does

  maybeFillByteEv.get

So that requires that maybeFillByteEv is defined when we determine we
needed to fill some bytes, and thus the dfdl:fillByteProperty is mandatory.

Seems to me we should just make the fill byte property mandatory. I
don't know if there are cases where we should actually consider it optional.

Solution 1:

Change RuntimePropertyMixins.scala so that maybeFillByEv is no longer a
Maybe, and it becomes something like this:

  final lazy val fillByteEv = {
    val ev = new FillByteEv(fillByte, charsetEv, tci)
    ev.compile(tunable)
    ev
  }

So fill byte is always required to be defined in the schema. And then
change all references to maybeFillByteEv to just fillByteEv. And follow
the variable until ProcessorStateBases.scala just becomes

  filleByteEv

instead of

  maybeFillByteEv.get

This way, if anything ever uses the fillByteEv variable, we require the
fillByte property to exist, and if it doesn't we'll get an SDE at schema
compile time. And then if fillByte is ever needed, then it will be
available.

The only issue with this approach is it might break schemas that don't
provide fillByte, since we now will always require fill byte where it
might not have been technically needed before. But I think we were just
getting lucky, and probably most schemas already defined it.

Solution 2:

Another option would be to just change ProcessorStateBases to be
something like this:

    if (termRuntimeData.maybeFillByteEv.isEmpty) {
      SDE("fillByte property required")
    } else {
      maybeCachedFillByte =
MaybeInt(termRuntimeData.maybeFillByteEv.get....)
    }

So at runtime, if we need to fill some bytes but maybeFillByteEv isn't
defined (i.e. the schema didn't define fillByte), then we throw a
Runtime SDE. This maintains backwards compatibility, but doesn't detect
the missing property until runtime, which is unfortunately. I'm not sure
if it's wroth maintaining that for this issue though. I'd probably lean
towards the first solution and just always require fillByte.


On 10/16/20 1:16 PM, Ramaka, Shashi wrote:
> I am working on DAFFODIL-2377: Abort instead of diagnostic message. 
> (https://issues.apache.org/jira/browse/DAFFODIL-2377 
> <https://issues.apache.org/jira/browse/DAFFODIL-2377>)
> 
> The attached files can be used to illustrate the bug.
> 
> daffodil parse -s s2377.xsd -o d2377.xml d2377.bin
> 
> daffodil unparse -s s2377.xsd d2377.xml
> 
> Unparsing results in the below error:
> 
> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
> 
> !!   An unexpected exception occurred. This is a bug!   !!
> 
> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
> 
> The schema has three elements. The first element has a length of 1 byte and 
> alignment of 1 byte while the next two elements have length = 1 and alignment 
> = 
> 2. The unparser is unparsing the first element correctly but throwing the 
> above 
> exception while determining the second element. Specifically it is failing 
> figuring out the fill byte to be used.
> 
> The unparser is failing on the highlighted line in ProcessorStateBase.scala 
> in 
> daffodil-runtime1:
> 
> final def fillByte: Byte = {
>    if (maybeCachedFillByte.isEmpty)
> *    maybeCachedFillByte = 
> MaybeInt(termRuntimeData.maybeFillByteEv.get.evaluate(this).toInt)
> *  maybeCachedFillByte.get.toByte
> }
> 
> Seems like the processor state in termRuntimeData does not have the fill byte 
> value from the schema. If I update the above fillByte to return a hard coded 
> byte value, unparse is working fine.
> 
> I’d appreciate any pointers on how to proceed from here.
> 
> Regards,
> 
>     Shashi Ramaka
> 
> sram...@owlcyberdefense.com <mailto:sram...@owlcyberdefense.com>
> 
>     Tel: 703-965-3656
> 

Reply via email to