This is an automated email from the ASF dual-hosted git repository.
olabusayo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new e4cc525f1 Parse Error on Out of Range Binary Integers
e4cc525f1 is described below
commit e4cc525f11af07033c2eaf06acc11d86b383233f
Author: olabusayoT <[email protected]>
AuthorDate: Thu Oct 10 18:39:44 2024 -0400
Parse Error on Out of Range Binary Integers
- currently we don't check the minimum lengths for signed/unsigned binary
ints and this causes issues when you try to set a binary int to 0 bits (RSDE),
so per the DFDL workgroup we add in these checks.
- add width check to unparse code and associated test
- fix bug where we weren't returning after UnparseError
- add SDEs for checks for non-expression fixed lengths
- currently we pass in isSigned boolean from ElementBaseGrammarMixin, but
we can use the new PrimType.PrimNumeric.isSigned member instead for simplicity.
We also added the minWidth member to simplify checking the minimum width of
PrimNumeric types
- add tunable allowSignedIntegerLength1Bit and update tests to use
- add tests for parse and unparse
- update failing tests
- make it a PE if nBits == 0 for PackedBinaryIntegerBaseParser
- add checkMinWidth and checkMaxWidth into BinaryNumberCheckWidth trait
- add tests for 0 bit length and multiple of 4 check
- add runtime multiple of 4 length check
Deprecation/Compatibility
Although still supported via the tunable allowSignedIntegerLength1Bit, it
is recommended that schemas be updated to not depend on 1-bit signed binary
integers. allowSignedIntegerLength1Bit=true may be deprecated and removed in
the future. Binary integers with 0 bit length are no longer supported.
DAFFODIL-2297
---
.../codegen/c/DaffodilCCodeGenerator.scala | 2 +-
.../BinaryIntegerKnownLengthCodeGenerator.scala | 3 +-
.../apache/daffodil/core/dsom/ElementBase.scala | 32 +-
.../core/grammar/ElementBaseGrammarMixin.scala | 47 +-
.../primitives/PrimitivesBinaryNumber.scala | 16 +-
.../primitives/PrimitivesIBM4690Packed.scala | 12 +-
.../grammar/primitives/PrimitivesLengthKind.scala | 11 +-
.../core/grammar/primitives/PrimitivesPacked.scala | 6 -
.../resources/org/apache/daffodil/xsd/dafext.xsd | 9 +
.../unparsers/runtime1/BinaryNumberUnparsers.scala | 51 +-
.../daffodil/runtime1/dpath/DFDLXFunctions.scala | 4 +-
.../apache/daffodil/runtime1/dpath/NodeInfo.scala | 59 +-
.../processors/IBM4690PackedDecimalParsers.scala | 9 +-
.../runtime1/processors/PackedBinaryTraits.scala | 58 +-
.../runtime1/processors/PackedDecimalParsers.scala | 9 +-
.../processors/parsers/BinaryNumberParsers.scala | 89 ++-
.../org/apache/daffodil/extensions/enum/enums.tdml | 2 +-
.../section02/validation_errors/Validation.tdml | 7 +-
.../ContentFramingProps.tdml | 2 +-
.../section12/lengthKind/ExplicitTests.tdml | 649 ++++++++++++++++++++-
.../length_properties/LengthProperties.tdml | 20 +-
.../apache/daffodil/section13/packed/packed.tdml | 52 +-
.../lengthKind/TestLengthKindExplicit.scala | 104 ++++
.../daffodil/section13/packed/TestPacked.scala | 10 +
24 files changed, 1107 insertions(+), 156 deletions(-)
diff --git
a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
index 959d97e33..92348ee81 100644
---
a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
+++
b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
@@ -278,7 +278,7 @@ object DaffodilCCodeGenerator
case g: BinaryDouble => binaryFloatGenerateCode(g.e, lengthInBits = 64,
cgState)
case g: BinaryFloat => binaryFloatGenerateCode(g.e, lengthInBits = 32,
cgState)
case g: BinaryIntegerKnownLength =>
- binaryIntegerKnownLengthGenerateCode(g.e, g.lengthInBits, g.signed,
cgState)
+ binaryIntegerKnownLengthGenerateCode(g.e, g.lengthInBits, cgState)
case g: CaptureContentLengthEnd => noop(g)
case g: CaptureContentLengthStart => noop(g)
case g: CaptureValueLengthEnd => noop(g)
diff --git
a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/BinaryIntegerKnownLengthCodeGenerator.scala
b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/BinaryIntegerKnownLengthCodeGenerator.scala
index 4a835c9ac..1d2476cb3 100644
---
a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/BinaryIntegerKnownLengthCodeGenerator.scala
+++
b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/BinaryIntegerKnownLengthCodeGenerator.scala
@@ -18,6 +18,7 @@
package org.apache.daffodil.codegen.c.generators
import org.apache.daffodil.core.dsom.ElementBase
+import org.apache.daffodil.runtime1.dpath.NodeInfo.PrimType.PrimNumeric
trait BinaryIntegerKnownLengthCodeGenerator extends BinaryValueCodeGenerator {
@@ -25,7 +26,6 @@ trait BinaryIntegerKnownLengthCodeGenerator extends
BinaryValueCodeGenerator {
def binaryIntegerKnownLengthGenerateCode(
e: ElementBase,
lengthInBits: Long,
- signed: Boolean,
cgState: CodeGeneratorState
): Unit = {
val cLengthInBits = lengthInBits match {
@@ -35,6 +35,7 @@ trait BinaryIntegerKnownLengthCodeGenerator extends
BinaryValueCodeGenerator {
case n if n <= 64 => 64
case _ => e.SDE("Binary integer lengths longer than 64 bits are not
supported.")
}
+ val signed = e.primType.asInstanceOf[PrimNumeric].isSigned
val primType = if (signed) s"int$cLengthInBits" else s"uint$cLengthInBits"
val addField = valueAddField(e, lengthInBits, primType, _, cgState)
val validateFixed = valueValidateFixed(e, _, cgState)
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala
index 3992415bc..825f69da8 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala
@@ -774,11 +774,37 @@ trait ElementBase
if (
result.isDefined && repElement.isSimpleType && representation ==
Representation.Binary
) {
+ val nBits = result.get
primType match {
case primNumeric: NodeInfo.PrimType.PrimNumeric =>
- if (primNumeric.width.isDefined) {
- val nBits = result.get
- val width = primNumeric.width.get
+ if (primNumeric.minWidth.isDefined) {
+ val minWidth = primNumeric.minWidth.get
+ if (nBits < minWidth) {
+ val isSigned = primNumeric.isSigned
+ val signedStr = if (isSigned) "a signed" else "an unsigned"
+ val outOfRangeFmtStr =
+ "Minimum length for %s binary integer is %d bit(s), number of
bits %d out of range. " +
+ "An unsigned integer with length 1 bit could be used
instead."
+ if (isSigned && tunable.allowSignedIntegerLength1Bit && nBits ==
1) {
+ SDW(
+ WarnID.SignedBinaryIntegerLength1Bit,
+ outOfRangeFmtStr,
+ signedStr,
+ minWidth,
+ nBits
+ )
+ } else {
+ SDE(
+ outOfRangeFmtStr,
+ signedStr,
+ minWidth,
+ nBits
+ )
+ }
+ }
+ }
+ if (primNumeric.maxWidth.isDefined) {
+ val width = primNumeric.maxWidth.get
if (nBits > width) {
SDE(
"Number of bits %d out of range for binary %s, must be between
1 and %d bits.",
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
index f9982d71a..12b53c352 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
@@ -786,7 +786,7 @@ trait ElementBaseGrammarMixin
) {
ConvertZonedCombinator(
this,
- new IBM4690PackedIntegerKnownLength(this, false,
binaryNumberKnownLengthInBits),
+ new IBM4690PackedIntegerKnownLength(this, binaryNumberKnownLengthInBits),
textConverter
)
}
@@ -796,7 +796,7 @@ trait ElementBaseGrammarMixin
) {
ConvertZonedCombinator(
this,
- new IBM4690PackedIntegerRuntimeLength(this, false),
+ new IBM4690PackedIntegerRuntimeLength(this),
textConverter
)
}
@@ -806,7 +806,7 @@ trait ElementBaseGrammarMixin
) {
ConvertZonedCombinator(
this,
- new IBM4690PackedIntegerDelimitedEndOfData(this, false),
+ new IBM4690PackedIntegerDelimitedEndOfData(this),
textConverter
)
}
@@ -816,7 +816,7 @@ trait ElementBaseGrammarMixin
) {
ConvertZonedCombinator(
this,
- new IBM4690PackedIntegerPrefixedLength(this, false),
+ new IBM4690PackedIntegerPrefixedLength(this),
textConverter
)
}
@@ -827,7 +827,6 @@ trait ElementBaseGrammarMixin
this,
new PackedIntegerKnownLength(
this,
- false,
packedSignCodes,
binaryNumberKnownLengthInBits
),
@@ -838,7 +837,7 @@ trait ElementBaseGrammarMixin
prod("packedRuntimeLengthCalendar", binaryCalendarRep ==
BinaryCalendarRep.Packed) {
ConvertZonedCombinator(
this,
- new PackedIntegerRuntimeLength(this, false, packedSignCodes),
+ new PackedIntegerRuntimeLength(this, packedSignCodes),
textConverter
)
}
@@ -846,7 +845,7 @@ trait ElementBaseGrammarMixin
prod("packedDelimitedLengthCalendar", binaryCalendarRep ==
BinaryCalendarRep.Packed) {
ConvertZonedCombinator(
this,
- new PackedIntegerDelimitedEndOfData(this, false, packedSignCodes),
+ new PackedIntegerDelimitedEndOfData(this, packedSignCodes),
textConverter
)
}
@@ -854,7 +853,7 @@ trait ElementBaseGrammarMixin
prod("packedPrefixedLengthCalendar", binaryCalendarRep ==
BinaryCalendarRep.Packed) {
ConvertZonedCombinator(
this,
- new PackedIntegerPrefixedLength(this, false, packedSignCodes),
+ new PackedIntegerPrefixedLength(this, packedSignCodes),
textConverter
)
}
@@ -897,7 +896,7 @@ trait ElementBaseGrammarMixin
private lazy val packedSignCodes =
PackedSignCodes(binaryPackedSignCodes, binaryNumberCheckPolicy)
- private def binaryIntegerValue(isSigned: Boolean) = {
+ private lazy val binaryIntegerValue = {
//
// Is it a single byte or smaller
//
@@ -910,10 +909,10 @@ trait ElementBaseGrammarMixin
}
(binaryNumberRep, lengthKind, binaryNumberKnownLengthInBits) match {
case (BinaryNumberRep.Binary, LengthKind.Prefixed, _) =>
- new BinaryIntegerPrefixedLength(this, isSigned)
- case (BinaryNumberRep.Binary, _, -1) => new
BinaryIntegerRuntimeLength(this, isSigned)
+ new BinaryIntegerPrefixedLength(this)
+ case (BinaryNumberRep.Binary, _, -1) => new
BinaryIntegerRuntimeLength(this)
case (BinaryNumberRep.Binary, _, _) =>
- new BinaryIntegerKnownLength(this, isSigned,
binaryNumberKnownLengthInBits)
+ new BinaryIntegerKnownLength(this, binaryNumberKnownLengthInBits)
case (_, LengthKind.Implicit, _) =>
SDE("lengthKind='implicit' is not allowed with packed binary formats")
case (_, _, _)
@@ -923,26 +922,25 @@ trait ElementBaseGrammarMixin
binaryNumberKnownLengthInBits
)
case (BinaryNumberRep.Packed, LengthKind.Delimited, -1) =>
- new PackedIntegerDelimitedEndOfData(this, isSigned, packedSignCodes)
+ new PackedIntegerDelimitedEndOfData(this, packedSignCodes)
case (BinaryNumberRep.Packed, LengthKind.Prefixed, -1) =>
- new PackedIntegerPrefixedLength(this, isSigned, packedSignCodes)
+ new PackedIntegerPrefixedLength(this, packedSignCodes)
case (BinaryNumberRep.Packed, _, -1) =>
- new PackedIntegerRuntimeLength(this, isSigned, packedSignCodes)
+ new PackedIntegerRuntimeLength(this, packedSignCodes)
case (BinaryNumberRep.Packed, _, _) =>
new PackedIntegerKnownLength(
this,
- isSigned,
packedSignCodes,
binaryNumberKnownLengthInBits
)
case (BinaryNumberRep.Ibm4690Packed, LengthKind.Delimited, -1) =>
- new IBM4690PackedIntegerDelimitedEndOfData(this, isSigned)
+ new IBM4690PackedIntegerDelimitedEndOfData(this)
case (BinaryNumberRep.Ibm4690Packed, LengthKind.Prefixed, -1) =>
- new IBM4690PackedIntegerPrefixedLength(this, isSigned)
+ new IBM4690PackedIntegerPrefixedLength(this)
case (BinaryNumberRep.Ibm4690Packed, _, -1) =>
- new IBM4690PackedIntegerRuntimeLength(this, isSigned)
+ new IBM4690PackedIntegerRuntimeLength(this)
case (BinaryNumberRep.Ibm4690Packed, _, _) =>
- new IBM4690PackedIntegerKnownLength(this, isSigned,
binaryNumberKnownLengthInBits)
+ new IBM4690PackedIntegerKnownLength(this,
binaryNumberKnownLengthInBits)
case (BinaryNumberRep.Bcd, _, _) =>
primType match {
case PrimType.Long | PrimType.Int | PrimType.Short | PrimType.Byte =>
@@ -974,13 +972,8 @@ trait ElementBaseGrammarMixin
// This is in the spirit of that section.
val res: Gram = primType match {
- case PrimType.Byte | PrimType.Short | PrimType.Int | PrimType.Long |
PrimType.Integer => {
- binaryIntegerValue(true)
- }
-
- case PrimType.UnsignedByte | PrimType.UnsignedShort |
PrimType.UnsignedInt |
- PrimType.UnsignedLong | PrimType.NonNegativeInteger => {
- binaryIntegerValue(false)
+ case n: PrimType.PrimNumeric if n.isInteger => {
+ binaryIntegerValue
}
case PrimType.Double | PrimType.Float => {
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryNumber.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryNumber.scala
index 2fbcad59e..8c2b4b594 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryNumber.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryNumber.scala
@@ -40,37 +40,33 @@ import
org.apache.daffodil.unparsers.runtime1.BinaryIntegerKnownLengthUnparser
import
org.apache.daffodil.unparsers.runtime1.BinaryIntegerPrefixedLengthUnparser
import
org.apache.daffodil.unparsers.runtime1.BinaryIntegerRuntimeLengthUnparser
-class BinaryIntegerRuntimeLength(val e: ElementBase, signed: Boolean)
- extends Terminal(e, true) {
+class BinaryIntegerRuntimeLength(val e: ElementBase) extends Terminal(e, true)
{
override lazy val parser = new BinaryIntegerRuntimeLengthParser(
e.elementRuntimeData,
- signed,
e.lengthEv,
e.lengthUnits
)
override lazy val unparser: Unparser = new
BinaryIntegerRuntimeLengthUnparser(
e.elementRuntimeData,
- signed,
e.lengthEv,
e.lengthUnits
)
}
-class BinaryIntegerKnownLength(val e: ElementBase, val signed: Boolean, val
lengthInBits: Long)
+class BinaryIntegerKnownLength(val e: ElementBase, val lengthInBits: Long)
extends Terminal(e, true) {
override lazy val parser = {
- new BinaryIntegerKnownLengthParser(e.elementRuntimeData, signed,
lengthInBits.toInt)
+ new BinaryIntegerKnownLengthParser(e.elementRuntimeData,
lengthInBits.toInt)
}
override lazy val unparser: Unparser =
- new BinaryIntegerKnownLengthUnparser(e.elementRuntimeData, signed,
lengthInBits.toInt)
+ new BinaryIntegerKnownLengthUnparser(e.elementRuntimeData,
lengthInBits.toInt)
}
-class BinaryIntegerPrefixedLength(val e: ElementBase, signed: Boolean)
- extends Terminal(e, true) {
+class BinaryIntegerPrefixedLength(val e: ElementBase) extends Terminal(e,
true) {
private lazy val erd = e.elementRuntimeData
private lazy val plerd = e.prefixedLengthElementDecl.elementRuntimeData
@@ -81,7 +77,6 @@ class BinaryIntegerPrefixedLength(val e: ElementBase, signed:
Boolean)
erd,
e.prefixedLengthBody.parser,
plerd,
- signed,
e.lengthUnits,
pladj
)
@@ -101,7 +96,6 @@ class BinaryIntegerPrefixedLength(val e: ElementBase,
signed: Boolean)
e.prefixedLengthBody.unparser,
plerd,
maybeNBits,
- signed,
e.lengthUnits,
pladj
)
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesIBM4690Packed.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesIBM4690Packed.scala
index 152af02cb..a5380474f 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesIBM4690Packed.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesIBM4690Packed.scala
@@ -33,11 +33,9 @@ import
org.apache.daffodil.unparsers.runtime1.IBM4690PackedIntegerKnownLengthUnp
import
org.apache.daffodil.unparsers.runtime1.IBM4690PackedIntegerPrefixedLengthUnparser
import
org.apache.daffodil.unparsers.runtime1.IBM4690PackedIntegerRuntimeLengthUnparser
-class IBM4690PackedIntegerRuntimeLength(val e: ElementBase, signed: Boolean)
- extends Terminal(e, true) {
+class IBM4690PackedIntegerRuntimeLength(val e: ElementBase) extends
Terminal(e, true) {
override lazy val parser = new IBM4690PackedIntegerRuntimeLengthParser(
e.elementRuntimeData,
- signed,
e.lengthEv,
e.lengthUnits
)
@@ -49,23 +47,21 @@ class IBM4690PackedIntegerRuntimeLength(val e: ElementBase,
signed: Boolean)
)
}
-class IBM4690PackedIntegerKnownLength(val e: ElementBase, signed: Boolean,
lengthInBits: Long)
+class IBM4690PackedIntegerKnownLength(val e: ElementBase, lengthInBits: Long)
extends Terminal(e, true) {
override lazy val parser =
- new IBM4690PackedIntegerKnownLengthParser(e.elementRuntimeData, signed,
lengthInBits.toInt)
+ new IBM4690PackedIntegerKnownLengthParser(e.elementRuntimeData,
lengthInBits.toInt)
override lazy val unparser: Unparser =
new IBM4690PackedIntegerKnownLengthUnparser(e.elementRuntimeData,
lengthInBits.toInt)
}
-class IBM4690PackedIntegerPrefixedLength(val e: ElementBase, signed: Boolean)
- extends Terminal(e, true) {
+class IBM4690PackedIntegerPrefixedLength(val e: ElementBase) extends
Terminal(e, true) {
override lazy val parser = new IBM4690PackedIntegerPrefixedLengthParser(
e.elementRuntimeData,
e.prefixedLengthBody.parser,
e.prefixedLengthElementDecl.elementRuntimeData,
- signed,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
)
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
index 9459267ce..21baad565 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
@@ -205,7 +205,6 @@ case class HexBinaryLengthPrefixed(e: ElementBase) extends
Terminal(e, true) {
abstract class PackedIntegerDelimited(
e: ElementBase,
- signed: Boolean,
packedSignCodes: PackedSignCodes
) extends StringDelimited(e) {
@@ -223,9 +222,8 @@ abstract class PackedIntegerDelimited(
case class PackedIntegerDelimitedEndOfData(
e: ElementBase,
- signed: Boolean,
packedSignCodes: PackedSignCodes
-) extends PackedIntegerDelimited(e, signed, packedSignCodes) {
+) extends PackedIntegerDelimited(e, packedSignCodes) {
val isDelimRequired: Boolean = false
}
@@ -289,8 +287,7 @@ case class BCDDecimalDelimitedEndOfData(e: ElementBase)
extends BCDDecimalDelimi
val isDelimRequired: Boolean = false
}
-abstract class IBM4690PackedIntegerDelimited(e: ElementBase, signed: Boolean)
- extends StringDelimited(e) {
+abstract class IBM4690PackedIntegerDelimited(e: ElementBase) extends
StringDelimited(e) {
override lazy val parser: DaffodilParser = new
IBM4690PackedIntegerDelimitedParser(
e.elementRuntimeData,
@@ -304,8 +301,8 @@ abstract class IBM4690PackedIntegerDelimited(e:
ElementBase, signed: Boolean)
)
}
-case class IBM4690PackedIntegerDelimitedEndOfData(e: ElementBase, signed:
Boolean)
- extends IBM4690PackedIntegerDelimited(e, signed) {
+case class IBM4690PackedIntegerDelimitedEndOfData(e: ElementBase)
+ extends IBM4690PackedIntegerDelimited(e) {
val isDelimRequired: Boolean = false
}
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesPacked.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesPacked.scala
index fef8199c6..c0f7a73ec 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesPacked.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesPacked.scala
@@ -36,12 +36,10 @@ import
org.apache.daffodil.unparsers.runtime1.PackedIntegerRuntimeLengthUnparser
class PackedIntegerRuntimeLength(
val e: ElementBase,
- signed: Boolean,
packedSignCodes: PackedSignCodes
) extends Terminal(e, true) {
override lazy val parser = new PackedIntegerRuntimeLengthParser(
e.elementRuntimeData,
- signed,
packedSignCodes,
e.lengthEv,
e.lengthUnits
@@ -57,14 +55,12 @@ class PackedIntegerRuntimeLength(
class PackedIntegerKnownLength(
val e: ElementBase,
- signed: Boolean,
packedSignCodes: PackedSignCodes,
lengthInBits: Long
) extends Terminal(e, true) {
override lazy val parser = new PackedIntegerKnownLengthParser(
e.elementRuntimeData,
- signed,
packedSignCodes,
lengthInBits.toInt
)
@@ -78,7 +74,6 @@ class PackedIntegerKnownLength(
class PackedIntegerPrefixedLength(
val e: ElementBase,
- signed: Boolean,
packedSignCodes: PackedSignCodes
) extends Terminal(e, true) {
@@ -86,7 +81,6 @@ class PackedIntegerPrefixedLength(
e.elementRuntimeData,
e.prefixedLengthBody.parser,
e.prefixedLengthElementDecl.elementRuntimeData,
- signed,
packedSignCodes,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
diff --git
a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
index d0e2f4a08..69ea3fdbb 100644
--- a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
+++ b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
@@ -137,6 +137,14 @@
</xs:documentation>
</xs:annotation>
</xs:element>
+ <xs:element name="allowSignedIntegerLength1Bit" type="xs:boolean"
default="true" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ When processing signed binary integers, which should have a
length of at least 2 bits, issue
+ a warning if the length is less than 2 bits by default,
otherwise (if false) issue a SDE or Processing Error.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
<xs:element name="blobChunkSizeInBytes" default="4096" minOccurs="0">
<xs:annotation>
<xs:documentation>
@@ -734,6 +742,7 @@
<xs:enumeration value="patternEncodingSlashW" />
<xs:enumeration value="queryStylePathExpression" />
<xs:enumeration value="regexPatternZeroLength" />
+ <xs:enumeration value="signedBinaryIntegerLength1Bit" />
<xs:enumeration value="textBidiError" />
<xs:enumeration value="textNumberPatternWarning" />
<xs:enumeration value="textOutputMinLengthOutOfRange" />
diff --git
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryNumberUnparsers.scala
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryNumberUnparsers.scala
index 2c5745fba..b4f99d9ab 100644
---
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryNumberUnparsers.scala
+++
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryNumberUnparsers.scala
@@ -24,13 +24,16 @@ import org.apache.daffodil.io.FormatInfo
import org.apache.daffodil.lib.exceptions.Assert
import org.apache.daffodil.lib.schema.annotation.props.gen.LengthUnits
import org.apache.daffodil.lib.schema.annotation.props.gen.YesNo
+import org.apache.daffodil.lib.schema.annotation.props.gen.YesNo.Yes
import org.apache.daffodil.lib.util.Maybe._
import org.apache.daffodil.lib.util.MaybeInt
import org.apache.daffodil.lib.util.Numbers._
+import org.apache.daffodil.runtime1.dpath.NodeInfo
import org.apache.daffodil.runtime1.processors.ElementRuntimeData
import org.apache.daffodil.runtime1.processors.Evaluatable
import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
import org.apache.daffodil.runtime1.processors.Processor
+import org.apache.daffodil.runtime1.processors.parsers.BinaryNumberCheckWidth
import org.apache.daffodil.runtime1.processors.parsers.HasKnownLengthInBits
import org.apache.daffodil.runtime1.processors.parsers.HasRuntimeExplicitLength
import org.apache.daffodil.runtime1.processors.unparsers._
@@ -56,12 +59,7 @@ abstract class BinaryNumberBaseUnparser(override val
context: ElementRuntimeData
val nBits = getBitLength(state)
val value = getNumberToPut(state)
val dos = state.dataOutputStream
- val res =
- if (nBits > 0) {
- putNumber(dos, value, nBits, state)
- } else {
- true
- }
+ val res = putNumber(dos, value, nBits, state)
if (!res) {
Assert.invariant(dos.maybeRelBitLimit0b.isDefined)
@@ -78,8 +76,11 @@ abstract class BinaryNumberBaseUnparser(override val
context: ElementRuntimeData
}
-abstract class BinaryIntegerBaseUnparser(e: ElementRuntimeData, signed:
Boolean)
- extends BinaryNumberBaseUnparser(e) {
+abstract class BinaryIntegerBaseUnparser(e: ElementRuntimeData)
+ extends BinaryNumberBaseUnparser(e)
+ with BinaryNumberCheckWidth {
+
+ private val primNumeric =
e.optPrimType.get.asInstanceOf[NodeInfo.PrimType.PrimNumeric]
override def putNumber(
dos: DataOutputStream,
@@ -87,8 +88,18 @@ abstract class BinaryIntegerBaseUnparser(e:
ElementRuntimeData, signed: Boolean)
nBits: Int,
finfo: FormatInfo
): Boolean = {
+ val state = finfo.asInstanceOf[UState]
+ if (primNumeric.minWidth.isDefined) {
+ val minWidth = primNumeric.minWidth.get
+ val isSigned = primNumeric.isSigned
+ checkMinWidth(state, isSigned, nBits, minWidth)
+ }
+ if (primNumeric.maxWidth.isDefined) {
+ val maxWidth = primNumeric.maxWidth.get
+ checkMaxWidth(state, nBits, maxWidth)
+ }
if (nBits > 64) {
- dos.putBigInt(asBigInt(value), nBits, signed, finfo)
+ dos.putBigInt(asBigInt(value), nBits, primNumeric.isSigned, finfo)
} else {
dos.putLong(asLong(value), nBits, finfo)
}
@@ -97,9 +108,8 @@ abstract class BinaryIntegerBaseUnparser(e:
ElementRuntimeData, signed: Boolean)
class BinaryIntegerKnownLengthUnparser(
e: ElementRuntimeData,
- signed: Boolean,
override val lengthInBits: Int
-) extends BinaryIntegerBaseUnparser(e, signed)
+) extends BinaryIntegerBaseUnparser(e)
with HasKnownLengthInBits {
override lazy val runtimeDependencies = Vector()
@@ -108,10 +118,9 @@ class BinaryIntegerKnownLengthUnparser(
class BinaryIntegerRuntimeLengthUnparser(
val e: ElementRuntimeData,
- signed: Boolean,
val lengthEv: Evaluatable[JLong],
val lengthUnits: LengthUnits
-) extends BinaryIntegerBaseUnparser(e, signed)
+) extends BinaryIntegerBaseUnparser(e)
with HasRuntimeExplicitLength {
override val runtimeDependencies = Vector(lengthEv)
@@ -122,12 +131,13 @@ class BinaryIntegerPrefixedLengthUnparser(
override val prefixedLengthUnparser: Unparser,
override val prefixedLengthERD: ElementRuntimeData,
maybeNBits: MaybeInt,
- signed: Boolean,
override val lengthUnits: LengthUnits,
override val prefixedLengthAdjustmentInUnits: Long
-) extends BinaryIntegerBaseUnparser(e: ElementRuntimeData, signed: Boolean)
+) extends BinaryIntegerBaseUnparser(e: ElementRuntimeData)
with KnownPrefixedLengthUnparserMixin {
+ private val primNumeric =
e.optPrimType.get.asInstanceOf[NodeInfo.PrimType.PrimNumeric]
+
override def childProcessors: Vector[Processor] =
Vector(prefixedLengthUnparser)
override lazy val runtimeDependencies = Vector()
@@ -140,7 +150,7 @@ class BinaryIntegerPrefixedLengthUnparser(
// bytes needed to represent the number
val value = getNumberToPut(s.asInstanceOf[UState])
val len = Math.max(asBigInt(value).bitLength, 1)
- val signedLen = if (signed) len + 1 else len
+ val signedLen = if (primNumeric.isSigned) len + 1 else len
(signedLen + 7) & ~0x7 // round up to nearest multilpe of 8
}
}
@@ -241,7 +251,8 @@ abstract class BinaryDecimalUnparserBase(
e: ElementRuntimeData,
signed: YesNo,
binaryDecimalVirtualPoint: Int
-) extends BinaryNumberBaseUnparser(e) {
+) extends BinaryNumberBaseUnparser(e)
+ with BinaryNumberCheckWidth {
override def getNumberToPut(state: UState): JNumber = {
val node = state.currentInfosetNode.asSimple
@@ -268,6 +279,10 @@ abstract class BinaryDecimalUnparserBase(
nBits: Int,
finfo: FormatInfo
): Boolean = {
- dos.putBigInt(asBigInt(value), nBits, signed == YesNo.Yes, finfo)
+ val state = finfo.asInstanceOf[UState]
+ val isSigned: Boolean = signed == Yes
+ val minWidth: Int = if (isSigned) 2 else 1
+ checkMinWidth(state, isSigned, nBits, minWidth)
+ dos.putBigInt(asBigInt(value), nBits, isSigned, finfo)
}
}
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DFDLXFunctions.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DFDLXFunctions.scala
index 5cec60fff..106d4740e 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DFDLXFunctions.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DFDLXFunctions.scala
@@ -54,7 +54,7 @@ case class DFDLXLeftShift(recipes: List[CompiledDPath],
argType: NodeInfo.Kind)
val shiftLong = arg2.getLong
val shift = shiftLong.toInt
- val width = argType.asInstanceOf[PrimNumeric].width.get
+ val width = argType.asInstanceOf[PrimNumeric].maxWidth.get
Assert.invariant(shift >= 0)
if (shift >= width)
dstate.SDE(
@@ -101,7 +101,7 @@ case class DFDLXRightShift(recipes: List[CompiledDPath],
argType: NodeInfo.Kind)
): DataValuePrimitive = {
val shiftLong = arg2.getLong
val shift = shiftLong.toInt
- val width = argType.asInstanceOf[PrimNumeric].width.get
+ val width = argType.asInstanceOf[PrimNumeric].maxWidth.get
Assert.invariant(shift >= 0)
if (shift >= width)
dstate.SDE(
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
index cb94dec31..5ce59bf1a 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
@@ -534,7 +534,9 @@ object NodeInfo extends Enum {
}
trait PrimNumeric { self: Numeric.Kind =>
- def width: MaybeInt
+ def isSigned: Boolean
+ def minWidth: MaybeInt
+ def maxWidth: MaybeInt
def isValid(n: Number): Boolean
protected def fromNumberNoCheck(n: Number): DataValueNumber
def fromNumber(n: Number): DataValueNumber = {
@@ -648,7 +650,9 @@ object NodeInfo extends Enum {
// toString would have a precision different than Float.MaxValue.toString
override val minStr = "-" + JFloat.MAX_VALUE.toString
override val maxStr = JFloat.MAX_VALUE.toString
- override val width: MaybeInt = MaybeInt(32)
+ override val isSigned: Boolean = true
+ override val minWidth: MaybeInt = MaybeInt(32)
+ override val maxWidth: MaybeInt = MaybeInt(32)
}
protected sealed trait DoubleKind extends SignedNumeric.Kind
@@ -667,7 +671,9 @@ object NodeInfo extends Enum {
override val max = JDouble.MAX_VALUE
override val minStr = "-" + JDouble.MAX_VALUE.toString
override val maxStr = JDouble.MAX_VALUE.toString
- override val width: MaybeInt = MaybeInt(64)
+ override val isSigned: Boolean = true
+ override val minWidth: MaybeInt = MaybeInt(64)
+ override val maxWidth: MaybeInt = MaybeInt(64)
}
protected sealed trait DecimalKind extends SignedNumeric.Kind
@@ -686,8 +692,9 @@ object NodeInfo extends Enum {
case _ => true
}
}
-
- override val width: MaybeInt = MaybeInt.Nope
+ override val isSigned: Boolean = true
+ override val minWidth: MaybeInt = MaybeInt.Nope
+ override val maxWidth: MaybeInt = MaybeInt.Nope
override def isInteger = false
}
@@ -708,8 +715,9 @@ object NodeInfo extends Enum {
case _ => true
}
}
-
- override val width: MaybeInt = MaybeInt.Nope
+ override val isSigned: Boolean = true
+ override val minWidth: MaybeInt = MaybeInt(2)
+ override val maxWidth: MaybeInt = MaybeInt.Nope
override def isInteger = true
}
@@ -725,7 +733,9 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueLong =
n.longValue
override val min = JLong.MIN_VALUE
override val max = JLong.MAX_VALUE
- override val width: MaybeInt = MaybeInt(64)
+ override val isSigned: Boolean = true
+ override val minWidth: MaybeInt = MaybeInt(2)
+ override val maxWidth: MaybeInt = MaybeInt(64)
}
protected sealed trait IntKind extends Long.Kind
@@ -739,7 +749,9 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueInt =
n.intValue
override val min = JInt.MIN_VALUE.toLong
override val max = JInt.MAX_VALUE.toLong
- override val width: MaybeInt = MaybeInt(32)
+ override val isSigned: Boolean = true
+ override val minWidth: MaybeInt = MaybeInt(2)
+ override val maxWidth: MaybeInt = MaybeInt(32)
}
protected sealed trait ShortKind extends Int.Kind
@@ -753,7 +765,9 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueShort =
n.shortValue
override val min = JShort.MIN_VALUE.toLong
override val max = JShort.MAX_VALUE.toLong
- override val width: MaybeInt = MaybeInt(16)
+ override val isSigned: Boolean = true
+ override val minWidth: MaybeInt = MaybeInt(2)
+ override val maxWidth: MaybeInt = MaybeInt(16)
}
protected sealed trait ByteKind extends Short.Kind
@@ -767,7 +781,9 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueByte =
n.byteValue
override val min = JByte.MIN_VALUE.toLong
override val max = JByte.MAX_VALUE.toLong
- override val width: MaybeInt = MaybeInt(8)
+ override val isSigned: Boolean = true
+ override val minWidth: MaybeInt = MaybeInt(2)
+ override val maxWidth: MaybeInt = MaybeInt(8)
}
protected sealed trait NonNegativeIntegerKind extends Integer.Kind
@@ -786,8 +802,9 @@ object NodeInfo extends Enum {
case f: JFloat if f.isInfinite || f.isNaN => false
case _ => n.longValue >= 0
}
-
- override val width: MaybeInt = MaybeInt.Nope
+ override val isSigned: Boolean = false
+ override val minWidth: MaybeInt = MaybeInt(1)
+ override val maxWidth: MaybeInt = MaybeInt.Nope
override def isInteger = true
}
@@ -814,7 +831,9 @@ object NodeInfo extends Enum {
}
val max = new JBigInt(1, scala.Array.fill(8)(0xff.toByte))
val maxBD = new JBigDecimal(max)
- override val width: MaybeInt = MaybeInt(64)
+ override val isSigned: Boolean = false
+ override val minWidth: MaybeInt = MaybeInt(1)
+ override val maxWidth: MaybeInt = MaybeInt(64)
override def isInteger = true
}
@@ -834,7 +853,9 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueLong =
n.longValue
override val min = 0L
override val max = 0xffffffffL
- override val width: MaybeInt = MaybeInt(32)
+ override val isSigned: Boolean = false
+ override val minWidth: MaybeInt = MaybeInt(1)
+ override val maxWidth: MaybeInt = MaybeInt(32)
}
protected sealed trait UnsignedShortKind extends UnsignedInt.Kind
@@ -848,7 +869,9 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueInt =
n.intValue
override val min = 0L
override val max = 0xffffL
- override val width: MaybeInt = MaybeInt(16)
+ override val isSigned: Boolean = false
+ override val minWidth: MaybeInt = MaybeInt(1)
+ override val maxWidth: MaybeInt = MaybeInt(16)
}
protected sealed trait UnsignedByteKind extends UnsignedShort.Kind
@@ -862,7 +885,9 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueShort =
n.shortValue
override val min = 0L
override val max = 0xffL
- override val width: MaybeInt = MaybeInt(8)
+ override val isSigned: Boolean = false
+ override val minWidth: MaybeInt = MaybeInt(1)
+ override val maxWidth: MaybeInt = MaybeInt(8)
}
protected sealed trait StringKind extends AnyAtomic.Kind
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/IBM4690PackedDecimalParsers.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/IBM4690PackedDecimalParsers.scala
index 36067c404..dc2799262 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/IBM4690PackedDecimalParsers.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/IBM4690PackedDecimalParsers.scala
@@ -81,10 +81,9 @@ class IBM4690PackedDecimalPrefixedLengthParser(
class IBM4690PackedIntegerRuntimeLengthParser(
val e: ElementRuntimeData,
- signed: Boolean,
val lengthEv: Evaluatable[JLong],
val lengthUnits: LengthUnits
-) extends PackedBinaryIntegerBaseParser(e, signed)
+) extends PackedBinaryIntegerBaseParser(e)
with HasRuntimeExplicitLength {
override def toBigInteger(num: Array[Byte]): JBigInteger =
@@ -96,9 +95,8 @@ class IBM4690PackedIntegerRuntimeLengthParser(
class IBM4690PackedIntegerKnownLengthParser(
e: ElementRuntimeData,
- signed: Boolean,
val lengthInBits: Int
-) extends PackedBinaryIntegerBaseParser(e, signed)
+) extends PackedBinaryIntegerBaseParser(e)
with HasKnownLengthInBits {
override def toBigInteger(num: Array[Byte]): JBigInteger =
@@ -112,10 +110,9 @@ class IBM4690PackedIntegerPrefixedLengthParser(
e: ElementRuntimeData,
override val prefixedLengthParser: Parser,
override val prefixedLengthERD: ElementRuntimeData,
- signed: Boolean,
override val lengthUnits: LengthUnits,
override val prefixedLengthAdjustmentInUnits: Long
-) extends PackedBinaryIntegerBaseParser(e, signed)
+) extends PackedBinaryIntegerBaseParser(e)
with PrefixedLengthParserMixin {
override def toBigInteger(num: Array[Byte]): JBigInteger =
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedBinaryTraits.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedBinaryTraits.scala
index 5030e0a68..ca7bedf41 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedBinaryTraits.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedBinaryTraits.scala
@@ -26,6 +26,7 @@ import org.apache.daffodil.lib.equality.TypeEqual
import org.apache.daffodil.lib.exceptions.Assert
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.MaybeChar
+import org.apache.daffodil.runtime1.dpath.NodeInfo
import org.apache.daffodil.runtime1.processors.ElementRuntimeData
import org.apache.daffodil.runtime1.processors.FieldDFAParseEv
import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
@@ -40,18 +41,52 @@ trait PackedBinaryConversion {
def toBigDecimal(num: Array[Byte], scale: Int): JBigDecimal
}
+trait PackedBinaryLengthCheck {
+ def PE(state: PState, str: String, args: Any*): Unit
+ def checkLengthNotEqualToZero(nBits: Int, start: PState, packedType:
String): Boolean = {
+ if (nBits == 0) {
+ PE(
+ start,
+ s"Number of bits %d out of range for a packed $packedType.",
+ nBits
+ )
+ false
+ } else {
+ true
+ }
+ }
+
+ def checkLengthIsMultipleOf4(nBits: Int, start: PState): Boolean = {
+ if ((nBits % 4) != 0) {
+ PE(
+ start,
+ "The given length (%s bits) must be a multiple of 4 when using packed
binary formats",
+ nBits
+ )
+ false
+ } else {
+ true
+ }
+ }
+}
+
abstract class PackedBinaryDecimalBaseParser(
override val context: ElementRuntimeData,
binaryDecimalVirtualPoint: Int
) extends PrimParser
- with PackedBinaryConversion {
+ with PackedBinaryConversion
+ with PackedBinaryLengthCheck {
override lazy val runtimeDependencies = Vector()
protected def getBitLength(s: ParseOrUnparseState): Int
def parse(start: PState): Unit = {
val nBits = getBitLength(start)
- if (nBits == 0) return // zero length is used for outputValueCalc often.
+ val lengthEqualsZero = !checkLengthNotEqualToZero(nBits, start, packedType
= "decimal")
+ if (lengthEqualsZero) return
+ val lengthNotMultipleOf4 = !checkLengthIsMultipleOf4(nBits, start)
+ if (lengthNotMultipleOf4) return
+
val dis = start.dataInputStream
if (!dis.isDefinedForLength(nBits)) {
@@ -69,17 +104,28 @@ abstract class PackedBinaryDecimalBaseParser(
}
abstract class PackedBinaryIntegerBaseParser(
- override val context: ElementRuntimeData,
- signed: Boolean = false
+ override val context: ElementRuntimeData
) extends PrimParser
- with PackedBinaryConversion {
+ with PackedBinaryConversion
+ with PackedBinaryLengthCheck {
override lazy val runtimeDependencies = Vector()
+ val signed = {
+ context.optPrimType.get match {
+ case n: NodeInfo.PrimType.PrimNumeric => n.isSigned
+ // context.optPrimType can be of type date/time via
ConvertZonedCombinator
+ case _ => false
+ }
+ }
protected def getBitLength(s: ParseOrUnparseState): Int
def parse(start: PState): Unit = {
val nBits = getBitLength(start)
- if (nBits == 0) return // zero length is used for outputValueCalc often.
+ val lengthEqualsZero = !checkLengthNotEqualToZero(nBits, start, packedType
= "integer")
+ if (lengthEqualsZero) return
+ val lengthNotMultipleOf4 = !checkLengthIsMultipleOf4(nBits, start)
+ if (lengthNotMultipleOf4) return
+
val dis = start.dataInputStream
if (!dis.isDefinedForLength(nBits)) {
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedDecimalParsers.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedDecimalParsers.scala
index 248322f3e..6f130de9f 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedDecimalParsers.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedDecimalParsers.scala
@@ -84,11 +84,10 @@ class PackedDecimalPrefixedLengthParser(
class PackedIntegerRuntimeLengthParser(
val e: ElementRuntimeData,
- signed: Boolean,
packedSignCodes: PackedSignCodes,
val lengthEv: Evaluatable[JLong],
val lengthUnits: LengthUnits
-) extends PackedBinaryIntegerBaseParser(e, signed)
+) extends PackedBinaryIntegerBaseParser(e)
with HasRuntimeExplicitLength {
override def toBigInteger(num: Array[Byte]): JBigInteger =
@@ -100,10 +99,9 @@ class PackedIntegerRuntimeLengthParser(
class PackedIntegerKnownLengthParser(
e: ElementRuntimeData,
- signed: Boolean,
packedSignCodes: PackedSignCodes,
val lengthInBits: Int
-) extends PackedBinaryIntegerBaseParser(e, signed)
+) extends PackedBinaryIntegerBaseParser(e)
with HasKnownLengthInBits {
override def toBigInteger(num: Array[Byte]): JBigInteger =
@@ -117,11 +115,10 @@ class PackedIntegerPrefixedLengthParser(
e: ElementRuntimeData,
override val prefixedLengthParser: Parser,
override val prefixedLengthERD: ElementRuntimeData,
- signed: Boolean,
packedSignCodes: PackedSignCodes,
override val lengthUnits: LengthUnits,
override val prefixedLengthAdjustmentInUnits: Long
-) extends PackedBinaryIntegerBaseParser(e, signed)
+) extends PackedBinaryIntegerBaseParser(e)
with PrefixedLengthParserMixin {
override def toBigInteger(num: Array[Byte]): JBigInteger =
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberParsers.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberParsers.scala
index a373be2fb..fac7a9078 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberParsers.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberParsers.scala
@@ -22,12 +22,14 @@ import java.math.{ BigDecimal => JBigDecimal, BigInteger =>
JBigInt }
import org.apache.daffodil.lib.schema.annotation.props.gen.LengthUnits
import org.apache.daffodil.lib.schema.annotation.props.gen.YesNo
+import org.apache.daffodil.lib.schema.annotation.props.gen.YesNo.Yes
import org.apache.daffodil.runtime1.dpath.InvalidPrimitiveDataException
import org.apache.daffodil.runtime1.dpath.NodeInfo
import org.apache.daffodil.runtime1.processors.ElementRuntimeData
import org.apache.daffodil.runtime1.processors.Evaluatable
import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
import org.apache.daffodil.runtime1.processors.Processor
+import org.apache.daffodil.runtime1.processors.unparsers.UState
class BinaryFloatParser(override val context: ElementRuntimeData) extends
PrimParser {
override lazy val runtimeDependencies = Vector()
@@ -100,13 +102,18 @@ abstract class BinaryDecimalParserBase(
override val context: ElementRuntimeData,
signed: YesNo,
binaryDecimalVirtualPoint: Int
-) extends PrimParser {
+) extends PrimParser
+ with BinaryNumberCheckWidth {
override lazy val runtimeDependencies = Vector()
protected def getBitLength(s: ParseOrUnparseState): Int
def parse(start: PState): Unit = {
val nBits = getBitLength(start)
+ val isSigned = signed == Yes
+ val minWidth = if (isSigned) 2 else 1
+ val res = checkMinWidth(start, isSigned, nBits, minWidth)
+ if (!res) return
val dis = start.dataInputStream
if (!dis.isDefinedForLength(nBits)) {
PENotEnoughBits(start, nBits, dis)
@@ -124,27 +131,24 @@ abstract class BinaryDecimalParserBase(
class BinaryIntegerRuntimeLengthParser(
val e: ElementRuntimeData,
- signed: Boolean,
val lengthEv: Evaluatable[JLong],
val lengthUnits: LengthUnits
-) extends BinaryIntegerBaseParser(e, signed)
+) extends BinaryIntegerBaseParser(e)
with HasRuntimeExplicitLength {}
class BinaryIntegerKnownLengthParser(
e: ElementRuntimeData,
- signed: Boolean,
val lengthInBits: Int
-) extends BinaryIntegerBaseParser(e, signed)
+) extends BinaryIntegerBaseParser(e)
with HasKnownLengthInBits {}
class BinaryIntegerPrefixedLengthParser(
e: ElementRuntimeData,
override val prefixedLengthParser: Parser,
override val prefixedLengthERD: ElementRuntimeData,
- signed: Boolean,
override val lengthUnits: LengthUnits,
override val prefixedLengthAdjustmentInUnits: Long
-) extends BinaryIntegerBaseParser(e, signed)
+) extends BinaryIntegerBaseParser(e)
with PrefixedLengthParserMixin {
override def childProcessors: Vector[Processor] =
Vector(prefixedLengthParser)
@@ -155,9 +159,9 @@ class BinaryIntegerPrefixedLengthParser(
}
abstract class BinaryIntegerBaseParser(
- override val context: ElementRuntimeData,
- signed: Boolean
-) extends PrimParser {
+ override val context: ElementRuntimeData
+) extends PrimParser
+ with BinaryNumberCheckWidth {
override lazy val runtimeDependencies = Vector()
protected def getBitLength(s: ParseOrUnparseState): Int
@@ -166,16 +170,16 @@ abstract class BinaryIntegerBaseParser(
def parse(start: PState): Unit = {
val nBits = getBitLength(start)
- if (nBits == 0) return // zero length is used for outputValueCalc often.
- if (primNumeric.width.isDefined) {
- val width = primNumeric.width.get
- if (nBits > width)
- PE(
- start,
- "Number of bits %d out of range, must be between 1 and %d bits.",
- nBits,
- width
- )
+ if (primNumeric.minWidth.isDefined) {
+ val minWidth = primNumeric.minWidth.get
+ val isSigned: Boolean = primNumeric.isSigned
+ val res = checkMinWidth(start, isSigned, nBits, minWidth)
+ if (!res) return
+ }
+ if (primNumeric.maxWidth.isDefined) {
+ val maxWidth = primNumeric.maxWidth.get
+ val res = checkMaxWidth(start, nBits, maxWidth)
+ if (!res) return
}
val dis = start.dataInputStream
if (!dis.isDefinedForLength(nBits)) {
@@ -184,7 +188,7 @@ abstract class BinaryIntegerBaseParser(
}
val num: JNumber =
- if (signed) {
+ if (primNumeric.isSigned) {
if (nBits > 64) { dis.getSignedBigInt(nBits, start) }
else { dis.getSignedLong(nBits, start) }
} else {
@@ -205,3 +209,46 @@ abstract class BinaryIntegerBaseParser(
start.simpleElement.overwriteDataValue(res)
}
}
+
+trait BinaryNumberCheckWidth {
+ def checkMinWidth(
+ state: ParseOrUnparseState,
+ isSigned: Boolean,
+ nBits: Int,
+ minWidth: Int
+ ): Boolean = {
+ if (
+ nBits < minWidth && !(isSigned &&
state.tunable.allowSignedIntegerLength1Bit && nBits == 1)
+ ) {
+ val signedStr = if (isSigned) "a signed" else "an unsigned"
+ val outOfRangeStr =
+ s"Minimum length for $signedStr binary number is $minWidth bit(s),
number of bits $nBits out of range. " +
+ "An unsigned number with length 1 bit could be used instead."
+ val procErr = state.toProcessingError(outOfRangeStr)
+ state match {
+ case s: PState =>
+ s.setFailed(procErr)
+ return false
+ case s: UState =>
+ s.toss(procErr)
+ }
+ }
+ true
+ }
+
+ def checkMaxWidth(state: ParseOrUnparseState, nBits: Int, maxWidth: Int):
Boolean = {
+ if (nBits > maxWidth) {
+ val procErr = state.toProcessingError(
+ s"Number of bits $nBits out of range, must be between 1 and $maxWidth
bits."
+ )
+ state match {
+ case s: PState =>
+ s.setFailed(procErr)
+ return false
+ case s: UState =>
+ s.toss(procErr)
+ }
+ }
+ true
+ }
+}
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enums.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enums.tdml
index 7923ae7c4..420596449 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enums.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enums.tdml
@@ -134,7 +134,7 @@
</element>
<simpleType name="myBit" dfdl:lengthKind="explicit" dfdl:length="1">
- <restriction base="xs:byte"/>
+ <restriction base="xs:unsignedByte"/>
</simpleType>
<simpleType name="enum1" dfdlx:repType="ex:myBit">
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
index 88bb88702..1467b4e70 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
@@ -2521,7 +2521,7 @@
<xs:element name="a" dfdl:lengthKind="implicit">
<xs:complexType>
<xs:sequence>
- <xs:element name="x" type="xs:int" dfdl:length="1" />
+ <xs:element name="x" type="xs:int" dfdl:length="2" />
<xs:element name="y" dfdl:length="7"
dfdl:encoding="X-DFDL-US-ASCII-7-BIT-PACKED"
dfdl:bitOrder="leastSignificantBitFirst"> <!-- causes runtime sde -->
<xs:simpleType>
<xs:restriction base="xs:string">
@@ -2537,7 +2537,10 @@
<tdml:parserTestCase name="runtimeSdeWithRestriction_1" root="a"
model="runtimeSdeWithRestriction"
validation="on">
- <tdml:document>a</tdml:document>
+ <tdml:document>
+ <tdml:documentPart type="bits">1</tdml:documentPart>
+ <tdml:documentPart type="text">a</tdml:documentPart>
+ </tdml:document>
<tdml:errors>
<tdml:error>Runtime Schema Definition Error</tdml:error>
<tdml:error>dfdl:bitOrder</tdml:error>
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section11/content_framing_properties/ContentFramingProps.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section11/content_framing_properties/ContentFramingProps.tdml
index 20f7cb22e..fe747f4a9 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section11/content_framing_properties/ContentFramingProps.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section11/content_framing_properties/ContentFramingProps.tdml
@@ -1319,7 +1319,7 @@
<xs:complexType>
<xs:sequence>
<!-- single bit field leaves us after first bit, and in MSBF bit
order -->
- <xs:element name="bit" type="xs:int" dfdl:lengthKind="explicit"
dfdl:length="1"
+ <xs:element name="bit" type="xs:unsignedInt"
dfdl:lengthKind="explicit" dfdl:length="1"
dfdl:representation="binary" dfdl:lengthUnits="bits"
dfdl:bitOrder="mostSignificantBitFirst"/>
<!-- this encoding can go on any bit boundary, but requires LSBF -->
<xs:element name="s" type="xs:string" dfdl:lengthKind="explicit"
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/ExplicitTests.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/ExplicitTests.tdml
index d55a92948..ef249f783 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/ExplicitTests.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/ExplicitTests.tdml
@@ -1415,6 +1415,22 @@
</tdml:errors>
</tdml:parserTestCase>
+ <tdml:unparserTestCase name="unparseInvalidIntBitLengthExpr" root="r"
model="invalidIntBitLengthExpr"
+ description="">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:r>
+ <ex:len>64</ex:len>
+ <ex:v>32</ex:v>
+ </ex:r>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:errors>
+ <tdml:error>64 out of range</tdml:error>
+ <tdml:error>between 1 and 32</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
+
<tdml:defineSchema name="invalidShortBitLengthExpr">
<xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
<dfdl:format ref="ex:GeneralFormat" representation="binary"/>
@@ -1490,7 +1506,7 @@
<xs:element name="nineBits" dfdl:lengthKind="explicit" dfdl:length="2">
<xs:complexType>
<xs:sequence>
- <xs:element name="bit" type="xs:int" dfdl:lengthKind="explicit"
dfdl:lengthUnits="bits" dfdl:length="1"/>
+ <xs:element name="bit" type="xs:unsignedInt"
dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="1"/>
<xs:element name="byte" type="xs:int" dfdl:lengthKind="explicit"
dfdl:lengthUnits="bits" dfdl:length="8"/>
</xs:sequence>
</xs:complexType>
@@ -1521,4 +1537,635 @@
</tdml:errors>
</tdml:parserTestCase>
+ <tdml:defineSchema name="BinaryIntegers">
+ <xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+ <dfdl:format ref="ex:GeneralFormat" representation="binary"
lengthUnits="bits"/>
+
+ <xs:simpleType name="upadding" dfdl:lengthKind="explicit">
+ <xs:restriction base="xs:unsignedInt">
+ <xs:enumeration value="0" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="spadding" dfdl:lengthKind="explicit">
+ <xs:restriction base="xs:int">
+ <xs:enumeration value="0" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="spare1" type="ex:upadding" dfdl:length="{ 0 }"/>
+ <xs:element name="spare2" type="ex:upadding" dfdl:length="{ 1 }"/>
+ <xs:element name="spare3" type="ex:spadding" dfdl:length="{ 1 }"/>
+ <xs:element name="spare4" type="ex:spadding" dfdl:length="{ 2 }"/>
+ <xs:element name="spare5">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedByte"
dfdl:outputValueCalc="{ 1 }"/>
+ <xs:element name="e1" type="ex:spadding" dfdl:length="{ ../ex:len
}"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="spare6">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedInt"
dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" dfdl:length="{ 1 }"/>
+ <xs:element name="e1" type="ex:upadding" dfdl:length="{ ../ex:len
}"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="spare7">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedByte"
dfdl:lengthUnits="bytes" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
+ <xs:element name="e1" type="ex:spadding" dfdl:length="{ ../ex:len
}"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="packed1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedByte"
dfdl:lengthUnits="bytes"/>
+ <xs:element name="e1" dfdl:binaryNumberRep="packed" type="xs:int"
+ dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes"
dfdl:length="{ ../ex:len }"
+ dfdl:binaryPackedSignCodes="C D F C"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="packed2">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedByte"
dfdl:lengthUnits="bytes"/>
+ <xs:element name="e1" dfdl:binaryNumberRep="ibm4690Packed"
type="xs:int"
+ dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes"
dfdl:length="{ ../ex:len }"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="packed3">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedByte"
dfdl:lengthUnits="bytes"/>
+ <xs:element name="e1" dfdl:binaryNumberRep="packed"
type="xs:unsignedInt"
+ dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes"
dfdl:length="{ ../ex:len }"
+ dfdl:binaryPackedSignCodes="C D F C"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="packed4">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedByte"
dfdl:lengthUnits="bytes"/>
+ <xs:element name="e1" dfdl:binaryNumberRep="ibm4690Packed"
type="xs:unsignedInt"
+ dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes"
dfdl:length="{ ../ex:len }"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="packed5" dfdl:binaryNumberRep="packed" type="xs:int"
+ dfdl:binaryPackedSignCodes="C D F C" dfdl:inputValueCalc="{ 4668 }"/>
+ </tdml:defineSchema>
+
+ <tdml:defineConfig name="disallowSignedIntegerLength1Bit">
+ <daf:tunables>
+
<daf:allowSignedIntegerLength1Bit>false</daf:allowSignedIntegerLength1Bit>
+ </daf:tunables>
+ </tdml:defineConfig>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryInteger1" root="spare1"
model="BinaryIntegers"
+ description="SDE when attempting to use zero-length
unsigned binary integer">
+ <tdml:document>
+ <tdml:documentPart type="byte">
+ ff
+ </tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Schema Definition Error</tdml:error>
+ <tdml:error>unsigned binary integer</tdml:error>
+ <tdml:error>1 bit(s)</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryInteger2" root="spare3"
model="BinaryIntegers"
+ description="SDE when attempting to use length 1 signed
binary integer"
+ config="disallowSignedIntegerLength1Bit">
+ <tdml:document>
+ <tdml:documentPart type="byte">
+ ff
+ </tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Schema Definition Error</tdml:error>
+ <tdml:error>signed binary integer</tdml:error>
+ <tdml:error>2 bit(s)</tdml:error>
+ <tdml:error>1 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryInteger3" root="spare1"
model="BinaryIntegers"
+ description="SDE when attempting to use zero-length
unsigned binary integer">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare1>0</ex:spare1>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:errors>
+ <tdml:error>Schema Definition Error</tdml:error>
+ <tdml:error>unsigned binary integer</tdml:error>
+ <tdml:error>1 bit(s)</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
+
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryInteger4" root="spare3"
model="BinaryIntegers"
+ description="SDE when attempting to use length 1
signed binary integer"
+ config="disallowSignedIntegerLength1Bit">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare3>0</ex:spare3>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:errors>
+ <tdml:error>Schema Definition Error</tdml:error>
+ <tdml:error>signed binary integer</tdml:error>
+ <tdml:error>2 bit(s)</tdml:error>
+ <tdml:error>1 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
+
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryInteger5" root="spare5"
model="BinaryIntegers"
+ description="UnParse Error when attempting to use
length 1 (expr) signed binary integer"
+ config="disallowSignedIntegerLength1Bit">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare5>
+ <ex:len></ex:len>
+ <ex:e1>-1</ex:e1>
+ </ex:spare5>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:errors>
+ <tdml:error>Unparse Error</tdml:error>
+ <tdml:error>signed binary number</tdml:error>
+ <tdml:error>2 bit(s)</tdml:error>
+ <tdml:error>1 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
+
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryInteger6" root="spare6"
model="BinaryIntegers"
+ description="Unparse Error when attempting to use
zero-length (expr) unsigned binary integer">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare6>
+ <ex:len>0</ex:len>
+ <ex:e1>65535</ex:e1>
+ </ex:spare6>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:errors>
+ <tdml:error>Unparse Error</tdml:error>
+ <tdml:error>unsigned binary number</tdml:error>
+ <tdml:error>1 bit(s)</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryInteger7" root="spare5"
model="BinaryIntegers"
+ description="no SDW when attempting to use length 1 (expr) signed binary
integer. This won't roundtrip
+ because signed integers need 2 bits, so it will unparse
only 1 bit which is unsigned"
+ roundTrip="false"
+ ignoreUnexpectedWarnings="false">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare5>
+ <ex:len>1</ex:len>
+ <ex:e1>-1</ex:e1>
+ </ex:spare5>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:document>
+ <tdml:documentPart type="byte">0180</tdml:documentPart>
+ </tdml:document>
+ </tdml:unparserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryInteger8" root="spare5"
model="BinaryIntegers"
+ description="no SDW when attempting to use length 1 (expr) signed binary
integer. This won't roundtrip
+ because signed integers need 2 bits, so it will unparse
only 1 bit which is unsigned"
+ roundTrip="false"
+ ignoreUnexpectedWarnings="false">
+ <tdml:document>
+ <tdml:documentPart type="byte">01</tdml:documentPart>
+ <tdml:documentPart type="bits">1</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare5>
+ <ex:len>1</ex:len>
+ <ex:e1>1</ex:e1>
+ </ex:spare5>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryInteger9" root="spare3"
model="BinaryIntegers"
+ description="SDW when attempting to use length 1 signed binary integer">
+ <tdml:document>
+ <tdml:documentPart type="bits">1</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare3>1</ex:spare3>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:warnings>
+ <tdml:warning>Schema Definition Warning</tdml:warning>
+ <tdml:warning>signed binary integer</tdml:warning>
+ <tdml:warning>2 bit(s)</tdml:warning>
+ <tdml:warning>1 out of range</tdml:warning>
+ </tdml:warnings>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryInteger10" root="packed1"
model="BinaryIntegers"
+ description="packed signed explicit binary integer"
+ ignoreUnexpectedWarnings="false">
+ <tdml:document>
+ <tdml:documentPart type="byte">00123C</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryInteger11" root="packed2"
model="BinaryIntegers"
+ description="ibm4690 packed signed explicit binary integer"
+ ignoreUnexpectedWarnings="false">
+ <tdml:document>
+ <tdml:documentPart type="byte">001088</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryInteger12" root="packed3"
model="BinaryIntegers"
+ description="packed unsigned explicit binary integer"
+ ignoreUnexpectedWarnings="false">
+ <tdml:document>
+ <tdml:documentPart type="byte">00123C</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryInteger13" root="packed4"
model="BinaryIntegers"
+ description="ibm4690 packed signed explicit binary integer"
+ ignoreUnexpectedWarnings="false">
+ <tdml:document>
+ <tdml:documentPart type="byte">001088</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="inRangeLengthBinaryInteger1" root="spare2"
model="BinaryIntegers"
+ description="No Parse Error when attempting to use in
range unsigned binary integer">
+ <tdml:document>
+ <tdml:documentPart type="bits">
+ 1
+ </tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare2>1</ex:spare2>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="inRangeLengthBinaryInteger2" root="spare4"
model="BinaryIntegers"
+ description="No Parse Error when attempting to use in
range signed binary integer">
+ <tdml:document>
+ <tdml:documentPart type="bits">
+ 11
+ </tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare4>-1</ex:spare4>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:unparserTestCase name="inRangeLengthBinaryInteger3" root="spare4"
model="BinaryIntegers"
+ description="No Unparse Error when attempting to use in range signed
binary integer">
+ <tdml:document>
+ <tdml:documentPart type="bits">
+ 11
+ </tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare4>-1</ex:spare4>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:unparserTestCase>
+
+ <tdml:unparserTestCase name="inRangeLengthBinaryInteger4" root="spare2"
model="BinaryIntegers"
+ description="No Unparse Error when attempting to use in range unsigned
binary integer">
+ <tdml:document>
+ <tdml:documentPart type="bits">
+ 1
+ </tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare2>1</ex:spare2>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:unparserTestCase>
+
+ <tdml:unparserTestCase name="inRangeLengthBinaryInteger5" root="spare7"
model="BinaryIntegers"
+ description="No SDW when attempting to use in range signed binary
integer"
+ ignoreUnexpectedWarnings="false">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare7>
+ <ex:len>2</ex:len>
+ <ex:e1>-1</ex:e1>
+ </ex:spare7>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:document>
+ <tdml:documentPart type="byte">02</tdml:documentPart>
+ <tdml:documentPart type="bits">11</tdml:documentPart>
+ </tdml:document>
+ </tdml:unparserTestCase>
+
+ <tdml:parserTestCase name="inRangeLengthBinaryInteger6" root="packed1"
model="BinaryIntegers"
+ description="packed explicit binary integer"
+ ignoreUnexpectedWarnings="false">
+ <tdml:document>
+ <tdml:documentPart type="byte">02123C</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:packed1>
+ <ex:len>2</ex:len>
+ <ex:e1>123</ex:e1>
+ </ex:packed1>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="inRangeLengthBinaryInteger7" root="packed2"
model="BinaryIntegers"
+ description="ibm4690 packed explicit binary integer"
+ ignoreUnexpectedWarnings="false">
+ <tdml:document>
+ <tdml:documentPart type="byte">021088</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:packed2>
+ <ex:len>2</ex:len>
+ <ex:e1>1088</ex:e1>
+ </ex:packed2>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:unparserTestCase name="inRangeLengthBinaryInteger8" root="spare7"
model="BinaryIntegers"
+ description="No Unparse Error when attempting to use in range signed
binary integer">
+ <tdml:document>
+ <tdml:documentPart type="byte">02</tdml:documentPart>
+ <tdml:documentPart type="bits">11</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare7>
+ <ex:len>2</ex:len>
+ <ex:e1>-1</ex:e1>
+ </ex:spare7>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:unparserTestCase>
+
+ <tdml:unparserTestCase name="inRangeLengthBinaryInteger9" root="spare6"
model="BinaryIntegers"
+ description="No Unparse Error when attempting to use in range unsigned
binary integer">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:spare6>
+ <ex:len>1</ex:len>
+ <ex:e1>1</ex:e1>
+ </ex:spare6>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:document>
+ <tdml:documentPart type="byte">01</tdml:documentPart>
+ <tdml:documentPart type="bits">1</tdml:documentPart>
+ </tdml:document>
+ </tdml:unparserTestCase>
+
+ <tdml:parserTestCase name="inRangeLengthBinaryInteger10" root="packed5"
model="BinaryIntegers"
+ description="No Parse Error when attempting to use in range packed
binary integer">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:packed5>4668</ex:packed5>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:document>
+ <tdml:documentPart type="byte"/>
+ </tdml:document>
+ </tdml:parserTestCase>
+
+ <tdml:defineSchema name="BinaryDecimals">
+ <xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+ <dfdl:format ref="ex:GeneralFormat" binaryDecimalVirtualPoint="0"
lengthKind="explicit" representation="binary" lengthUnits="bits"/>
+
+ <xs:simpleType name="udec" dfdl:decimalSigned="no" >
+ <xs:restriction base="xs:decimal"/>
+ </xs:simpleType>
+
+ <xs:simpleType name="sdec" dfdl:decimalSigned="yes">
+ <xs:restriction base="xs:decimal"/>
+ </xs:simpleType>
+
+ <xs:element name="dec1" type="ex:udec" dfdl:length="{ 0 }"/>
+ <xs:element name="dec2" type="ex:udec" dfdl:length="{ 1 }"/>
+ <xs:element name="dec3" type="ex:sdec" dfdl:length="{ 1 }"/>
+ <xs:element name="dec4" type="ex:sdec" dfdl:length="{ 2 }"/>
+ <xs:element name="dec5" dfdl:lengthKind="implicit">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedByte" dfdl:length="1"/>
+ <xs:element name="e1" type="ex:udec" dfdl:length="{ ../ex:len }"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="dec6" dfdl:lengthKind="implicit">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedByte" dfdl:length="1"/>
+ <xs:element name="e1" type="ex:sdec" dfdl:length="{ ../ex:len }"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </tdml:defineSchema>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryDecimal1" root="dec1"
model="BinaryDecimals"
+ description="PE when attempting to use zero-length unsigned binary
decimal">
+ <tdml:document>
+ <tdml:documentPart type="byte">
+ ff
+ </tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>unsigned binary number</tdml:error>
+ <tdml:error>1 bit(s)</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryDecimal2" root="dec3"
model="BinaryDecimals"
+ description="SDE when attempting to use length 1 signed binary decimal"
+ config="disallowSignedIntegerLength1Bit">
+ <tdml:document>
+ <tdml:documentPart type="byte">
+ ff
+ </tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>signed binary number</tdml:error>
+ <tdml:error>2 bit(s)</tdml:error>
+ <tdml:error>1 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryDecimal3" root="dec1"
model="BinaryDecimals"
+ description="UE when attempting to use zero-length unsigned binary
decimal">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:dec1>1</ex:dec1>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:errors>
+ <tdml:error>Unparse Error</tdml:error>
+ <tdml:error>unsigned binary number</tdml:error>
+ <tdml:error>1 bit(s)</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
+
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryDecimal4" root="dec3"
model="BinaryDecimals"
+ description="SDE when attempting to use length 1 signed binary decimal"
+ config="disallowSignedIntegerLength1Bit">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:dec3>1</ex:dec3>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:errors>
+ <tdml:error>Unparse Error</tdml:error>
+ <tdml:error>signed binary number</tdml:error>
+ <tdml:error>2 bit(s)</tdml:error>
+ <tdml:error>1 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryDecimal5" root="dec3"
model="BinaryDecimals"
+ description="no SDW when attempting to use length 1 signed binary
decimal"
+ ignoreUnexpectedWarnings="false">
+ <tdml:document>
+ <tdml:documentPart type="bits">1</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:dec3>1</ex:dec3>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryDecimal6" root="dec3"
model="BinaryDecimals"
+ description="no SDW when attempting to use length 1 signed binary
decimal"
+ ignoreUnexpectedWarnings="false">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:dec3>1</ex:dec3>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:document>
+ <tdml:documentPart type="bits">1</tdml:documentPart>
+ </tdml:document>
+ </tdml:unparserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryDecimal7" root="dec6"
model="BinaryDecimals"
+ description="PE when attempting to use length 0 signed binary decimal">
+ <tdml:document>
+ <tdml:documentPart type="byte">00</tdml:documentPart>
+ <tdml:documentPart type="bits">1</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>signed binary number</tdml:error>
+ <tdml:error>2 bit(s)</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryDecimal8" root="dec6"
model="BinaryDecimals"
+ description="UE when attempting to use length 0 signed binary decimal">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:dec6>
+ <ex:len>0</ex:len>
+ <ex:e1>1</ex:e1>
+ </ex:dec6>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:errors>
+ <tdml:error>Unparse Error</tdml:error>
+ <tdml:error>signed binary number</tdml:error>
+ <tdml:error>2 bit(s)</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
+
+ <tdml:parserTestCase name="outOfRangeLengthBinaryDecimal9" root="dec5"
model="BinaryDecimals"
+ description="PE when attempting to use length 0 unsigned binary decimal">
+ <tdml:document>
+ <tdml:documentPart type="byte">00</tdml:documentPart>
+ <tdml:documentPart type="bits">1</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>signed binary number</tdml:error>
+ <tdml:error>1 bit(s)</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:unparserTestCase name="outOfRangeLengthBinaryDecimal10" root="dec5"
model="BinaryDecimals"
+ description="UE when attempting to use length 0 unsigned binary decimal">
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:dec5>
+ <ex:len>0</ex:len>
+ <ex:e1>1</ex:e1>
+ </ex:dec5>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:errors>
+ <tdml:error>Unparse Error</tdml:error>
+ <tdml:error>signed binary number</tdml:error>
+ <tdml:error>1 bit(s)</tdml:error>
+ <tdml:error>0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
</tdml:testSuite>
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/length_properties/LengthProperties.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/length_properties/LengthProperties.tdml
index 866691abc..52c8ed0f0 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/length_properties/LengthProperties.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/length_properties/LengthProperties.tdml
@@ -913,7 +913,7 @@
<xs:element name="bit27" type="xs:int" dfdl:lengthKind="explicit"
dfdl:length="9" dfdl:byteOrder="bigEndian" />
<xs:element name="bit28" type="xs:int" dfdl:lengthKind="explicit"
dfdl:length="13" dfdl:byteOrder="bigEndian" />
<xs:element name="bit29" type="xs:long" dfdl:lengthKind="explicit"
dfdl:length="3" dfdl:byteOrder="bigEndian" />
- <xs:element name="bit30" type="xs:byte" dfdl:lengthKind="explicit"
dfdl:length="1" dfdl:byteOrder="bigEndian" />
+ <xs:element name="bit30" type="xs:byte" dfdl:lengthKind="explicit"
dfdl:length="2" dfdl:byteOrder="bigEndian" />
<xs:element name="bit31" type="xs:short" dfdl:lengthKind="implicit"
dfdl:byteOrder="bigEndian" />
<xs:element name="bit32" type="xs:int" dfdl:lengthKind="implicit"
dfdl:byteOrder="bigEndian" />
@@ -922,15 +922,15 @@
<xs:complexType>
<xs:sequence dfdl:separator="">
<xs:element name="bit33" type="xs:byte" dfdl:lengthKind="implicit"
dfdl:byteOrder="bigEndian" />
- <xs:element name="bit34" type="xs:short" dfdl:lengthKind="explicit"
dfdl:length="1" dfdl:byteOrder="littleEndian"/>
+ <xs:element name="bit34" type="xs:short" dfdl:lengthKind="explicit"
dfdl:length="2" dfdl:byteOrder="littleEndian"/>
<xs:element name="bit35" type="xs:int" dfdl:lengthKind="implicit"
dfdl:byteOrder="littleEndian"/>
- <xs:element name="bit36" type="xs:int" dfdl:lengthKind="explicit"
dfdl:length="1" dfdl:byteOrder="bigEndian"/>
- <xs:element name="bit37" type="xs:long" dfdl:lengthKind="explicit"
dfdl:length="1" dfdl:byteOrder="bigEndian"/>
+ <xs:element name="bit36" type="xs:int" dfdl:lengthKind="explicit"
dfdl:length="2" dfdl:byteOrder="bigEndian"/>
+ <xs:element name="bit37" type="xs:long" dfdl:lengthKind="explicit"
dfdl:length="2" dfdl:byteOrder="bigEndian"/>
</xs:sequence>
</xs:complexType>
</xs:element>
- <xs:element name="bit38" type="xs:short" dfdl:lengthKind="explicit"
dfdl:length="1" dfdl:byteOrder="bigEndian" />
+ <xs:element name="bit38" type="xs:short" dfdl:lengthKind="explicit"
dfdl:length="2" dfdl:byteOrder="bigEndian" />
</tdml:defineSchema>
@@ -1118,7 +1118,7 @@
<tdml:parserTestCase name="bitShort3"
root="bit38" model="bitSchema" description="Section 12 Length Properties -
DFDL-12-161R">
<tdml:document>
- <tdml:documentPart type="bits"><![CDATA[1]]></tdml:documentPart>
+ <tdml:documentPart type="bits"><![CDATA[01]]></tdml:documentPart>
</tdml:document>
<tdml:infoset>
<tdml:dfdlInfoset>
@@ -1190,7 +1190,7 @@
<tdml:parserTestCase name="bitByte"
root="bit30" model="bitSchema" description="Section 12 Length Properties -
DFDL-12-161R">
<tdml:document>
- <tdml:documentPart type="bits"><![CDATA[0]]></tdml:documentPart>
+ <tdml:documentPart type="bits"><![CDATA[00]]></tdml:documentPart>
</tdml:document>
<tdml:infoset>
<tdml:dfdlInfoset>
@@ -1245,10 +1245,10 @@
root="s4" model="bitSchema" description="Section 12 Length Properties -
DFDL-12-161R">
<tdml:document>
<tdml:documentPart type="bits">00101010</tdml:documentPart>
- <tdml:documentPart type="bits">1</tdml:documentPart>
+ <tdml:documentPart type="bits">01</tdml:documentPart>
<tdml:documentPart type="bits">00000000 00000000 00000000
00000001</tdml:documentPart>
- <tdml:documentPart type="bits">0</tdml:documentPart>
- <tdml:documentPart type="bits">1</tdml:documentPart>
+ <tdml:documentPart type="bits">00</tdml:documentPart>
+ <tdml:documentPart type="bits">01</tdml:documentPart>
</tdml:document>
<tdml:infoset>
<tdml:dfdlInfoset>
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section13/packed/packed.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section13/packed/packed.tdml
index b8e643fa0..572476206 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section13/packed/packed.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section13/packed/packed.tdml
@@ -124,11 +124,22 @@
<tdml:defineSchema name="s8">
<xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
<dfdl:format ref="ex:GeneralFormat" lengthKind="explicit"
encoding="X-DFDL-HEX-MSBF" occursCountKind="implicit"
- textNumberCheckPolicy="strict" textNumberPadCharacter="0"
textNumberJustification="right"
+ textNumberPadCharacter="0" textNumberJustification="right"
lengthUnits="bits" binaryNumberRep="packed" binaryPackedSignCodes="C D F
C" binaryNumberCheckPolicy="strict"/>
<xs:element name="int01" type="xs:int" dfdl:representation="binary"
dfdl:length="7" />
+ <xs:element name="int02" type="xs:decimal" dfdl:representation="binary"
dfdl:length="0" dfdl:binaryDecimalVirtualPoint="0" />
+
+ <xs:element name="int03" dfdl:lengthKind="implicit">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="len" type="xs:unsignedInt" dfdl:length="1"
dfdl:lengthUnits="bytes"/>
+ <xs:element name="value" type="xs:decimal"
dfdl:representation="binary" dfdl:length="{ ../ex:len}"
dfdl:binaryDecimalVirtualPoint="0" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
</tdml:defineSchema>
<tdml:defineSchema name="s9">
@@ -416,6 +427,45 @@
</tdml:errors>
</tdml:parserTestCase>
+ <tdml:parserTestCase name="zeroLengthPackedCharset" root="int02" model="s8"
+ description="Attempting to use a length of 0 bits with IBM4690 Packed
Decimal should result in SDE">
+
+ <tdml:document>
+ <tdml:documentPart type="bits">0010101</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>bits 0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="runtimeLengthPackedCharset1" root="int03"
model="s8"
+ description="Attempting to use a runtime length with IBM4690 Packed
Decimal should result in PE">
+
+ <tdml:document>
+ <tdml:documentPart type="byte">00</tdml:documentPart>
+ <tdml:documentPart type="bits">0010101</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>bits 0 out of range</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="runtimeLengthPackedCharset2" root="int03"
model="s8"
+ description="Attempting to use a runtime length with IBM4690 Packed
Decimal should result in PE">
+
+ <tdml:document>
+ <tdml:documentPart type="byte">07</tdml:documentPart>
+ <tdml:documentPart type="bits">0010101</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>The given length</tdml:error>
+ <tdml:error>must be a multiple of 4 when using packed binary
formats</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
<tdml:parserTestCase name="packedCharset10" root="int01" model="s11"
description="Attempting to use an alignment of 1 bit with Packed Decimal
should result in SDE">
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindExplicit.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindExplicit.scala
index f8a62cb6d..c787fc226 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindExplicit.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindExplicit.scala
@@ -164,6 +164,9 @@ class TestLengthKindExplicit {
@Test def test_invalidIntBitLengthExpr(): Unit = {
runner.runOneTest("invalidIntBitLengthExpr")
}
+ @Test def test_unparseInvalidIntBitLengthExpr(): Unit = {
+ runner.runOneTest("unparseInvalidIntBitLengthExpr")
+ }
@Test def test_invalidShortBitLengthExpr(): Unit = {
runner.runOneTest("invalidShortBitLengthExpr")
@@ -180,4 +183,105 @@ class TestLengthKindExplicit {
@Test def test_insufficientBitsByte(): Unit = {
runner.runOneTest("insufficientBitsByte")
}
+
+ // DFDL-2297
+ @Test def test_outOfRangeLengthBinaryInteger1(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger1")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger2(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger2")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger3(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger3")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger4(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger4")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger5(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger5")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger6(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger6")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger7(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger7")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger8(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger8")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger9(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger9")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger10(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger10")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger11(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger11")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger12(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger12")
+ }
+ @Test def test_outOfRangeLengthBinaryInteger13(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryInteger13")
+ }
+ @Test def test_inRangeLengthBinaryInteger1(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger1")
+ }
+ @Test def test_inRangeLengthBinaryInteger2(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger2")
+ }
+ @Test def test_inRangeLengthBinaryInteger3(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger3")
+ }
+ @Test def test_inRangeLengthBinaryInteger4(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger4")
+ }
+ @Test def test_inRangeLengthBinaryInteger5(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger5")
+ }
+ @Test def test_inRangeLengthBinaryInteger6(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger6")
+ }
+ @Test def test_inRangeLengthBinaryInteger7(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger7")
+ }
+ @Test def test_inRangeLengthBinaryInteger8(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger8")
+ }
+ @Test def test_inRangeLengthBinaryInteger9(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger9")
+ }
+ @Test def test_inRangeLengthBinaryInteger10(): Unit = {
+ runner.runOneTest("inRangeLengthBinaryInteger10")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal1(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal1")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal2(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal2")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal3(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal3")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal4(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal4")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal5(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal5")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal6(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal6")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal7(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal7")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal8(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal8")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal9(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal9")
+ }
+ @Test def test_outOfRangeLengthBinaryDecimal10(): Unit = {
+ runner.runOneTest("outOfRangeLengthBinaryDecimal10")
+ }
}
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/section13/packed/TestPacked.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/section13/packed/TestPacked.scala
index cab7f1be8..029ab04ea 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/section13/packed/TestPacked.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/section13/packed/TestPacked.scala
@@ -51,6 +51,16 @@ class TestPacked {
@Test def testPackedCharset09(): Unit = {
runner.runOneTest("packedCharset09") }
@Test def testPackedCharset10(): Unit = {
runner.runOneTest("packedCharset10") }
+ @Test def testZeroLengthPackedCharset(): Unit = {
+ runner.runOneTest("zeroLengthPackedCharset")
+ }
+ @Test def testRuntimeLengthPackedCharset1(): Unit = {
+ runner.runOneTest("runtimeLengthPackedCharset1")
+ }
+ @Test def testRuntimeLengthPackedCharset2(): Unit = {
+ runner.runOneTest("runtimeLengthPackedCharset2")
+ }
+
@Test def testBCDCharset01(): Unit = { runner.runOneTest("bcdCharset01") }
@Test def testBCDCharset02(): Unit = { runner.runOneTest("bcdCharset02") }
@Test def testBCDCharset03(): Unit = { runner.runOneTest("bcdCharset03") }