You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by mm...@apache.org on 2023/03/02 15:40:47 UTC

[daffodil] branch main updated: Add checks for bit lengths

This is an automated email from the ASF dual-hosted git repository.

mmcgann 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 d5c884869 Add checks for bit lengths
d5c884869 is described below

commit d5c884869e88a7d45e5ae21fd254d7166111d444
Author: Mike McGann <mm...@owlcyberdefense.com>
AuthorDate: Fri Feb 24 16:17:44 2023 -0500

    Add checks for bit lengths
    
    Daffodil was allowing bit lengths on binary types that exceed the
    width of the type even though this is not allowed by the DFDL
    specification. This change adds a check at compile time to see if the
    bit length value is valid when specified as a constant and at runtime
    when the bit length is specified an expression.
    
    DAFFODIL-1704
---
 .../org/apache/daffodil/codegen/c/ex_nums.dfdl.xsd |   2 +-
 .../apache/daffodil/core/dsom/ElementBase.scala    |  53 +++-
 .../runtime1/SpecifiedLengthUnparsers.scala        |   1 -
 .../processors/parsers/BinaryNumberParsers.scala   |  10 +
 .../section05/simple_types/SimpleTypes.tdml        |   2 +-
 .../section12/lengthKind/ExplicitTests.tdml        | 290 ++++++++++++++++++++-
 .../section12/lengthKind/PrefixedTests.tdml        | 268 ++++++++++++++++++-
 .../lengthKind/TestLengthKindExplicit.scala        |  46 ++++
 .../lengthKind/TestLengthKindPrefixed.scala        |  28 ++
 9 files changed, 682 insertions(+), 18 deletions(-)

diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/ex_nums.dfdl.xsd b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/ex_nums.dfdl.xsd
index bc431cfbb..eecf2827d 100644
--- a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/ex_nums.dfdl.xsd
+++ b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/ex_nums.dfdl.xsd
@@ -138,7 +138,7 @@
                                         dfdl:byteOrder="littleEndian"/>
                             <xs:element name="le_int8" type="xs:byte"
                                         dfdl:byteOrder="littleEndian"/>
-                            <xs:element name="le_int46" type="xs:int"
+                            <xs:element name="le_int46" type="xs:integer"
                                         dfdl:byteOrder="littleEndian"
                                         dfdl:length="46"
                                         dfdl:lengthKind="explicit"/>
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 3d41d87cf..d925cb20a 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
@@ -705,8 +705,9 @@ trait ElementBase
     // of a variable-width charset, so greater than 0, but we don't know
     // exactly.
     Assert.usage(repElement.isFixedLength)
-    if (repElement.lengthKind =:= LengthKind.Explicit) repElement.lengthEv.optConstant.get
-    else {
+    if (repElement.lengthKind =:= LengthKind.Explicit) {
+      repElement.lengthEv.optConstant.get
+    } else {
       Assert.invariant(repElement.lengthKind =:= LengthKind.Implicit)
       // it's a string with implicit length. get from facets
       schemaDefinitionUnless(
@@ -750,21 +751,47 @@ trait ElementBase
 
   // FIXME: bless this method. Deprecate and remove other less reliable things.
   final lazy val maybeFixedLengthInBits: MaybeULong = {
-    if (isRepresented && repElement.isFixedLength) {
-      val bitsMultiplier = repElement.lengthUnits match {
-        case LengthUnits.Bits => 1
-        case LengthUnits.Bytes => 8
-        case LengthUnits.Characters =>
-          if (knownEncodingIsFixedWidth) knownEncodingWidthInBits else -1
-      }
-      if (bitsMultiplier > 0) {
-        MaybeULong(repElement.fixedLengthValue * bitsMultiplier)
+    val result = {
+      if (isRepresented && repElement.isFixedLength) {
+        val bitsMultiplier = repElement.lengthUnits match {
+          case LengthUnits.Bits => 1
+          case LengthUnits.Bytes => 8
+          case LengthUnits.Characters =>
+            if (knownEncodingIsFixedWidth) knownEncodingWidthInBits else -1
+        }
+        if (bitsMultiplier > 0) {
+          MaybeULong(repElement.fixedLengthValue * bitsMultiplier)
+        } else {
+          MaybeULong.Nope
+        }
       } else {
         MaybeULong.Nope
       }
-    } else {
-      MaybeULong.Nope
     }
+
+    // Validate that the number of bits does not exceed the maximum number of
+    // bits allowed for the type
+    if (
+      result.isDefined && repElement.isSimpleType && representation == Representation.Binary
+    ) {
+      primType match {
+        case primNumeric: NodeInfo.PrimType.PrimNumeric =>
+          if (primNumeric.width.isDefined) {
+            val nBits = result.get
+            val width = primNumeric.width.get
+            if (nBits > width) {
+              SDE(
+                "Number of bits %d out of range for binary %s, must be between 1 and %d bits.",
+                nBits,
+                primNumeric.globalQName,
+                width,
+              )
+            }
+          }
+        case _ =>
+      }
+    }
+    result
   }
 
   /**
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
index ebbfbe546..422d15276 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
@@ -225,7 +225,6 @@ final class SpecifiedLengthExplicitImplicitUnparser(
    * will be provided in bits.
    */
   def unparseBits(state: UState): Unit = {
-
     val maybeTLBits = getMaybeTL(state, targetLengthInBitsEv)
 
     if (maybeTLBits.isDefined) {
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 919f0386b..60da09183 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
@@ -167,6 +167,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,
+        )
+    }
     val dis = start.dataInputStream
     if (!dis.isDefinedForLength(nBits)) {
       PENotEnoughBits(start, nBits, dis.remainingBits)
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml
index 18a3c1676..ee7b5bcd5 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml
@@ -216,7 +216,7 @@
 
     <xs:element name="posint01" type="xs:nonNegativeInteger" />
     <xs:element name="int01" type="xs:int" />
-    <xs:element name="int02" type="xs:int" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="65" />
+    <xs:element name="int02" type="xs:int" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="16" />
     <xs:element name="l_1" type="xs:long" />
     <xs:element name="s_1" type="xs:short" />
     <xs:element name="b_01" type="xs:byte" />
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 b99bab4a1..b9facca16 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
@@ -831,7 +831,7 @@
     <dfdl:format ref="ex:GeneralFormat" />
 
     <xs:element name="stringy" type="xs:string" dfdl:lengthUnits="bytes" dfdl:lengthKind="explicit" dfdl:length="6"/>
-    <xs:element name="inty" type="xs:int" dfdl:representation="binary" dfdl:lengthUnits="bytes" dfdl:lengthKind="explicit" dfdl:length="6"/>
+    <xs:element name="inty" type="xs:integer" dfdl:representation="binary" dfdl:lengthUnits="bytes" dfdl:lengthKind="explicit" dfdl:length="6"/>
     <xs:element name="inty02" type="xs:int" dfdl:representation="binary" dfdl:lengthUnits="bytes" dfdl:lengthKind="explicit" dfdl:length="2"/>
 
   </tdml:defineSchema>
@@ -1050,4 +1050,292 @@
     </tdml:warnings>
   </tdml:parserTestCase>
 
+  <!--
+    These tests check for the condition where the bit length exceeds the width of the
+    specified type when the value is a constant. All numeric signed and unsigned types are checked
+    using invalid bit lengths, and there is one check for an invalid byte length.
+  -->
+  <tdml:defineSchema name="invalidUnsignedLongBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r" type="xs:unsignedLong" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="128"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedLongBitLength" root="r" model="invalidUnsignedLongBitLength"
+                       description="Check for invalid bit length with an unsigned long">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>128 out of range</tdml:error>
+      <tdml:error>between 1 and 64</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidUnsignedLongByteLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r" type="xs:unsignedLong" dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" dfdl:length="16"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedLongByteLength" root="r" model="invalidUnsignedLongByteLength"
+                       description="Check for invalid byte length with an unsigned long">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>128 out of range</tdml:error>
+      <tdml:error>between 1 and 64</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidUnsignedIntBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r" type="xs:unsignedInt" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="64"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedIntBitLength" root="r" model="invalidUnsignedIntBitLength"
+                       description="Check for invalid bit length with an unsigned int">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>64 out of range</tdml:error>
+      <tdml:error>between 1 and 32</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidUnsignedShortBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r" type="xs:unsignedShort" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="32"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedShortBitLength" root="r" model="invalidUnsignedShortBitLength"
+                       description="Check for invalid bit length with an unsigned short">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>32 out of range</tdml:error>
+      <tdml:error>between 1 and 16</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidUnsignedByteBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r" type="xs:unsignedByte" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="16"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedByteBitLength" root="r" model="invalidUnsignedByteBitLength"
+                       description="Check for invalid bit length with an unsigned byte">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>16 out of range</tdml:error>
+      <tdml:error>between 1 and 8</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidLongBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r" type="xs:long" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="128"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidLongBitLength" root="r" model="invalidLongBitLength"
+                       description="Check for invalid bit length with a signed long">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>128 out of range</tdml:error>
+      <tdml:error>between 1 and 64</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidIntBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r" type="xs:int" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="64"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidIntBitLength" root="r" model="invalidIntBitLength"
+                       description="Check for invalid bit length with an signed in">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>64 out of range</tdml:error>
+      <tdml:error>between 1 and 32</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidShortBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r" type="xs:short" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="32"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidShortBitLength" root="r" model="invalidShortBitLength"
+                       description="Check for invalid bit length with a signed short">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>32 out of range</tdml:error>
+      <tdml:error>between 1 and 16</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidByteBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r" type="xs:byte" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="16"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidByteBitLength" root="r" model="invalidByteBitLength"
+                       description="Check for invalid bit length with a signed byte">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>16 out of range</tdml:error>
+      <tdml:error>between 1 and 8</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <!--
+  These tests check for the condition where the bit length exceeds the width of the
+  specified type when the value is an expression. All numeric signed types are checked
+  using invalid bit lengths.
+  -->
+  <tdml:defineSchema name="invalidLongBitLengthExpr">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="len" type="xs:unsignedByte"/>
+          <xs:element name="v" type="xs:long" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="{ ../ex:len }"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidLongBitLengthExpr" root="r" model="invalidLongBitLengthExpr"
+                       description="">
+    <tdml:document>
+      <tdml:documentPart type="byte">
+        80
+        ff ff ff ff
+        ff ff ff ff
+        ff ff ff ff
+        ff ff ff ff
+      </tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>128 out of range</tdml:error>
+      <tdml:error>between 1 and 64</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidIntBitLengthExpr">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="len" type="xs:unsignedByte"/>
+          <xs:element name="v" type="xs:int" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="{ ../ex:len }"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidIntBitLengthExpr" root="r" model="invalidIntBitLengthExpr"
+                       description="">
+    <tdml:document>
+      <tdml:documentPart type="byte">
+        40
+        ff ff ff ff
+        ff ff ff ff
+      </tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>64 out of range</tdml:error>
+      <tdml:error>between 1 and 32</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidShortBitLengthExpr">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="len" type="xs:unsignedByte"/>
+          <xs:element name="v" type="xs:short" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="{ ../ex:len }"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidShortBitLengthExpr" root="r" model="invalidShortBitLengthExpr"
+                       description="">
+    <tdml:document>
+      <tdml:documentPart type="byte">
+        20
+        ff ff ff ff
+      </tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>32 out of range</tdml:error>
+      <tdml:error>between 1 and 16</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidByteBitLengthExpr">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:element name="r">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="len" type="xs:unsignedByte"/>
+          <xs:element name="v" type="xs:byte" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="{ ../ex:len }"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidByteBitLengthExpr" root="r" model="invalidByteBitLengthExpr"
+                       description="">
+    <tdml:document>
+      <tdml:documentPart type="byte">
+        10
+        ff ff
+      </tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>16 out of range</tdml:error>
+      <tdml:error>between 1 and 8</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
 </tdml:testSuite>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/PrefixedTests.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/PrefixedTests.tdml
index 253e407d0..1d486ec80 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/PrefixedTests.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/PrefixedTests.tdml
@@ -407,7 +407,7 @@
 
     <xs:simpleType name="plSlash1_string_prefix"
        dfdl:lengthKind="explicit" dfdl:length="4" dfdl:lengthUnits="bytes">
-      <xs:restriction base="xs:unsignedByte" />
+      <xs:restriction base="xs:unsignedInt" />
     </xs:simpleType>
 
     <xs:element name="plSlash1_data">
@@ -2588,4 +2588,270 @@
     </tdml:warnings>
   </tdml:parserTestCase>
 
+  <!--
+  These tests check for the condition where the bit length exceeds the width of the
+  specified type when the value is a constant. All numeric signed and unsigned types are checked
+  using invalid bit lengths, and there is one check for an invalid byte length.
+  -->
+  <tdml:defineSchema name="invalidUnsignedLongBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:simpleType name="prefixedUnsignedLong"
+                   dfdl:representation="binary"
+                   dfdl:lengthKind="explicit"
+                   dfdl:lengthUnits="bits"
+                   dfdl:length="128">
+      <xs:restriction base="xs:unsignedLong"/>
+    </xs:simpleType>
+
+    <xs:element name="r" type="xs:unsignedLong"
+                dfdl:lengthKind="prefixed"
+                dfdl:prefixLengthType="ex:prefixedUnsignedLong"
+                dfdl:prefixIncludesPrefixLength="no"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedLongBitLength" root="r" model="invalidUnsignedLongBitLength"
+                       description="Check for invalid bit length with an unsigned long">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>128 out of range</tdml:error>
+      <tdml:error>between 1 and 64</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidUnsignedLongByteLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:simpleType name="prefixedUnsignedLong"
+                   dfdl:representation="binary"
+                   dfdl:lengthKind="explicit"
+                   dfdl:lengthUnits="bytes"
+                   dfdl:length="16">
+      <xs:restriction base="xs:unsignedLong"/>
+    </xs:simpleType>
+
+    <xs:element name="r" type="xs:unsignedLong"
+                dfdl:lengthKind="prefixed"
+                dfdl:prefixLengthType="ex:prefixedUnsignedLong"
+                dfdl:prefixIncludesPrefixLength="no"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedLongByteLength" root="r" model="invalidUnsignedLongByteLength"
+                       description="Check for invalid byte length with an unsigned long">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>128 out of range</tdml:error>
+      <tdml:error>between 1 and 64</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidUnsignedIntBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:simpleType name="prefixedUnsignedInt"
+                   dfdl:representation="binary"
+                   dfdl:lengthKind="explicit"
+                   dfdl:lengthUnits="bits"
+                   dfdl:length="64">
+      <xs:restriction base="xs:unsignedInt"/>
+    </xs:simpleType>
+
+    <xs:element name="r" type="xs:unsignedInt"
+                dfdl:lengthKind="prefixed"
+                dfdl:prefixLengthType="ex:prefixedUnsignedInt"
+                dfdl:prefixIncludesPrefixLength="no"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedIntBitLength" root="r" model="invalidUnsignedIntBitLength"
+                       description="Check for invalid bit length with an unsigned int">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>64 out of range</tdml:error>
+      <tdml:error>between 1 and 32</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidUnsignedShortBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:simpleType name="prefixedUnsignedShort"
+                   dfdl:representation="binary"
+                   dfdl:lengthKind="explicit"
+                   dfdl:lengthUnits="bits"
+                   dfdl:length="32">
+      <xs:restriction base="xs:unsignedShort"/>
+    </xs:simpleType>
+
+    <xs:element name="r" type="xs:unsignedShort"
+                dfdl:lengthKind="prefixed"
+                dfdl:prefixLengthType="ex:prefixedUnsignedShort"
+                dfdl:prefixIncludesPrefixLength="no"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedShortBitLength" root="r" model="invalidUnsignedShortBitLength"
+                       description="Check for invalid bit length with an unsigned short">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>32 out of range</tdml:error>
+      <tdml:error>between 1 and 16</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidUnsignedByteBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:simpleType name="prefixedUnsignedByte"
+                   dfdl:representation="binary"
+                   dfdl:lengthKind="explicit"
+                   dfdl:lengthUnits="bits"
+                   dfdl:length="16">
+      <xs:restriction base="xs:unsignedByte"/>
+    </xs:simpleType>
+
+    <xs:element name="r" type="xs:unsignedByte"
+                dfdl:lengthKind="prefixed"
+                dfdl:prefixLengthType="ex:prefixedUnsignedByte"
+                dfdl:prefixIncludesPrefixLength="no"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidUnsignedByteBitLength" root="r" model="invalidUnsignedByteBitLength"
+                       description="Check for invalid bit length with an unsigned byte">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>16 out of range</tdml:error>
+      <tdml:error>between 1 and 8</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidLongBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:simpleType name="prefixedLong"
+                   dfdl:representation="binary"
+                   dfdl:lengthKind="explicit"
+                   dfdl:lengthUnits="bits"
+                   dfdl:length="128">
+      <xs:restriction base="xs:long"/>
+    </xs:simpleType>
+
+    <xs:element name="r" type="xs:long"
+                dfdl:lengthKind="prefixed"
+                dfdl:prefixLengthType="ex:prefixedLong"
+                dfdl:prefixIncludesPrefixLength="no"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidLongBitLength" root="r" model="invalidLongBitLength"
+                       description="Check for invalid bit length with a long">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>128 out of range</tdml:error>
+      <tdml:error>between 1 and 64</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidIntBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:simpleType name="prefixedInt"
+                   dfdl:representation="binary"
+                   dfdl:lengthKind="explicit"
+                   dfdl:lengthUnits="bits"
+                   dfdl:length="64">
+      <xs:restriction base="xs:int"/>
+    </xs:simpleType>
+
+    <xs:element name="r" type="xs:int"
+                dfdl:lengthKind="prefixed"
+                dfdl:prefixLengthType="ex:prefixedInt"
+                dfdl:prefixIncludesPrefixLength="no"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidIntBitLength" root="r" model="invalidIntBitLength"
+                       description="Check for invalid bit length with an int">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>64 out of range</tdml:error>
+      <tdml:error>between 1 and 32</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidShortBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:simpleType name="prefixedShort"
+                   dfdl:representation="binary"
+                   dfdl:lengthKind="explicit"
+                   dfdl:lengthUnits="bits"
+                   dfdl:length="32">
+      <xs:restriction base="xs:short"/>
+    </xs:simpleType>
+
+    <xs:element name="r" type="xs:short"
+                dfdl:lengthKind="prefixed"
+                dfdl:prefixLengthType="ex:prefixedShort"
+                dfdl:prefixIncludesPrefixLength="no"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidShortBitLength" root="r" model="invalidShortBitLength"
+                       description="Check for invalid bit length with a short">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>32 out of range</tdml:error>
+      <tdml:error>between 1 and 16</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:defineSchema name="invalidByteBitLength">
+    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+    <xs:simpleType name="prefixedByte"
+                   dfdl:representation="binary"
+                   dfdl:lengthKind="explicit"
+                   dfdl:lengthUnits="bits"
+                   dfdl:length="16">
+      <xs:restriction base="xs:byte"/>
+    </xs:simpleType>
+
+    <xs:element name="r" type="xs:byte"
+                dfdl:lengthKind="prefixed"
+                dfdl:prefixLengthType="ex:prefixedByte"
+                dfdl:prefixIncludesPrefixLength="no"/>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="invalidByteBitLength" root="r" model="invalidByteBitLength"
+                       description="Check for invalid bit length with a byte">
+    <tdml:document>
+      <tdml:documentPart type="byte">ff</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>16 out of range</tdml:error>
+      <tdml:error>between 1 and 8</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
 </tdml:testSuite>
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 e2f41fd61..c5df7b6b3 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
@@ -107,4 +107,50 @@ class TestLengthKindExplicit {
   @Test def test_invalidLengthUnitsDecimalWarning_explicit(): Unit = {
     runner.runOneTest("invalidLengthUnitsDecimalWarning_explicit")
   }
+
+  @Test def test_invalidUnsignedLongBitLength(): Unit = {
+    runner.runOneTest("invalidUnsignedLongBitLength")
+  }
+
+  @Test def test_invalidUnsignedLongByteLength(): Unit = {
+    runner.runOneTest("invalidUnsignedLongByteLength")
+  }
+  @Test def test_invalidUnsignedIntBitLength(): Unit = {
+    runner.runOneTest("invalidUnsignedIntBitLength")
+  }
+  @Test def test_invalidUnsignedShortBitLength(): Unit = {
+    runner.runOneTest("invalidUnsignedShortBitLength")
+  }
+  @Test def test_invalidUnsignedByteBitLength(): Unit = {
+    runner.runOneTest("invalidUnsignedByteBitLength")
+  }
+
+  @Test def test_invalidLongBitLength(): Unit = {
+    runner.runOneTest("invalidLongBitLength")
+  }
+  @Test def test_invalidIntBitLength(): Unit = {
+    runner.runOneTest("invalidIntBitLength")
+  }
+  @Test def test_invalidShortBitLength(): Unit = {
+    runner.runOneTest("invalidShortBitLength")
+  }
+  @Test def test_invalidByteBitLength(): Unit = {
+    runner.runOneTest("invalidByteBitLength")
+  }
+
+  @Test def test_invalidLongBitLengthExpr(): Unit = {
+    runner.runOneTest("invalidLongBitLengthExpr")
+  }
+
+  @Test def test_invalidIntBitLengthExpr(): Unit = {
+    runner.runOneTest("invalidIntBitLengthExpr")
+  }
+
+  @Test def test_invalidShortBitLengthExpr(): Unit = {
+    runner.runOneTest("invalidShortBitLengthExpr")
+  }
+
+  @Test def test_invalidByteBitLengthExpr(): Unit = {
+    runner.runOneTest("invalidByteBitLengthExpr")
+  }
 }
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindPrefixed.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindPrefixed.scala
index de1e6092d..b9570eb65 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindPrefixed.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindPrefixed.scala
@@ -281,4 +281,32 @@ class TestLengthKindPrefixed {
     runner.runOneTest("invalidLengthUnits_prefixed")
   }
 
+  @Test def test_invalidUnsignedLongBitLength(): Unit = {
+    runner.runOneTest("invalidUnsignedLongBitLength")
+  }
+  @Test def test_invalidUnsignedLongByteLength(): Unit = {
+    runner.runOneTest("invalidUnsignedLongByteLength")
+  }
+  @Test def test_invalidUnsignedIntBitLength(): Unit = {
+    runner.runOneTest("invalidUnsignedIntBitLength")
+  }
+  @Test def test_invalidUnsignedShortBitLength(): Unit = {
+    runner.runOneTest("invalidUnsignedShortBitLength")
+  }
+  @Test def test_invalidUnsignedByteBitLength(): Unit = {
+    runner.runOneTest("invalidUnsignedByteBitLength")
+  }
+
+  @Test def test_invalidLongBitLength(): Unit = {
+    runner.runOneTest("invalidLongBitLength")
+  }
+  @Test def test_invalidIntBitLength(): Unit = {
+    runner.runOneTest("invalidIntBitLength")
+  }
+  @Test def test_invalidShortBitLength(): Unit = {
+    runner.runOneTest("invalidShortBitLength")
+  }
+  @Test def test_invalidByteBitLength(): Unit = {
+    runner.runOneTest("invalidByteBitLength")
+  }
 }