This is an automated email from the ASF dual-hosted git repository.
slawrence 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 fadde3242 SDE if dfdlx:bitAnd, dfdlx:bitOr, or dfdlx:bitXor arguments
do not match signedness
fadde3242 is described below
commit fadde324222e23150f701853fb2f1a8caef81dbe
Author: Steve Lawrence <[email protected]>
AuthorDate: Thu Dec 4 09:03:48 2025 -0500
SDE if dfdlx:bitAnd, dfdlx:bitOr, or dfdlx:bitXor arguments do not match
signedness
These functions are not well defined if the arguments do not match in
signedness. This modifies these functions to create a schema definition
error if the functions do not match in signedness, which matches the
extension documentation.
DAFFODIL-3049
---
.../apache/daffodil/core/dpath/Expression.scala | 21 ++++++----
.../section23/dfdl_functions/BitFunctionsAnd.tdml | 45 +++++++++++++++++++++-
.../section23/dfdl_functions/BitFunctionsOr.tdml | 45 +++++++++++++++++++++-
.../section23/dfdl_functions/BitFunctionsXor.tdml | 43 +++++++++++++++++++++
.../dfdl_expressions/TestBitFunctions.scala | 12 ++++++
5 files changed, 157 insertions(+), 9 deletions(-)
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
index 408cb9a10..6d018d5c8 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
@@ -2467,14 +2467,21 @@ case class DFDLXBitBinaryExpr(
override lazy val inherentType = {
val arg0Type = args(0).inherentType
val arg1Type = args(1).inherentType
+
+ (arg0Type, arg1Type) match {
+ case (_: NodeInfo.Long.Kind, _: NodeInfo.Long.Kind) => // noop
+ case (_: NodeInfo.UnsignedLong.Kind, _: NodeInfo.UnsignedLong.Kind) =>
// noop
+ case _ => {
+ SDE(
+ "Both arguments for %s must be either xs:unsignedLong or xs:long or
a subtype of those, and must match in signedness, but was %s and %s",
+ nameAsParsed,
+ arg0Type.globalQName,
+ arg1Type.globalQName
+ )
+ }
+ }
+
val argInherentType = if (arg1Type.isSubtypeOf(arg0Type)) arg0Type else
arg1Type
- schemaDefinitionUnless(
- argInherentType.isSubtypeOf(NodeInfo.PrimType.UnsignedLong) ||
argInherentType
- .isSubtypeOf(NodeInfo.PrimType.Long),
- "Both arguments for %s must be either xs:unsignedLong or xs:long or a
subtype of those, but was %s.",
- nameAsParsed,
- argInherentType.globalQName
- )
argInherentType
}
override def targetTypeForSubexpression(subexp: Expression): NodeInfo.Kind =
inherentType
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsAnd.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsAnd.tdml
index 8c79b0fb8..d7af78bed 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsAnd.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsAnd.tdml
@@ -164,6 +164,18 @@
</xs:complexType>
</xs:element>
+ <xs:element name="testIntegerAnd" type="xs:integer"
+ dfdl:inputValueCalc="{ dfdlx:bitAnd(xs:integer(1), xs:long(1)) }" />
+
+ <xs:element name="testNonNegativeIntegerAnd" type="xs:nonNegativeInteger"
+ dfdl:inputValueCalc="{ dfdlx:bitAnd(xs:nonNegativeInteger(1),
xs:unsignedLong(1)) }" />
+
+ <xs:element name="testDifferentSignednessAnd" type="xs:long"
+ dfdl:inputValueCalc="{ dfdlx:bitAnd(xs:long(1), xs:unsignedLong(1)) }" />
+
+ <xs:element name="testPromotionAnd" type="xs:long"
+ dfdl:inputValueCalc="{ dfdlx:bitAnd(xs:byte(1), xs:short(257)) }" />
+
</tdml:defineSchema>
<tdml:parserTestCase name="testIntAnd" root="testIntAnd"
model="BitFunctions">
@@ -326,4 +338,35 @@
</tdml:dfdlInfoset>
</tdml:infoset>
</tdml:parserTestCase>
-</tdml:testSuite>
\ No newline at end of file
+
+ <tdml:parserTestCase name="testIntegerAnd" root="testIntegerAnd"
model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>xs:unsignedLong or xs:long or a subtype of those</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testNonNegativeIntegerAnd"
root="testNonNegativeIntegerAnd" model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>xs:unsignedLong or xs:long or a subtype of those</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testDifferentSignednessAnd"
root="testDifferentSignednessAnd" model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>must match in signedness</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testPromotionAnd" root="testPromotionAnd"
model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:testPromotionAnd>1</ex:testPromotionAnd>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+</tdml:testSuite>
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsOr.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsOr.tdml
index d2bb3e6e1..cecdeaa82 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsOr.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsOr.tdml
@@ -164,6 +164,18 @@
</xs:complexType>
</xs:element>
+ <xs:element name="testIntegerOr" type="xs:integer"
+ dfdl:inputValueCalc="{ dfdlx:bitOr(xs:integer(1), xs:long(1)) }" />
+
+ <xs:element name="testNonNegativeIntegerOr" type="xs:nonNegativeInteger"
+ dfdl:inputValueCalc="{ dfdlx:bitOr(xs:nonNegativeInteger(1),
xs:unsignedLong(1)) }" />
+
+ <xs:element name="testDifferentSignednessOr" type="xs:long"
+ dfdl:inputValueCalc="{ dfdlx:bitOr(xs:long(1), xs:unsignedLong(1)) }" />
+
+ <xs:element name="testPromotionOr" type="xs:long"
+ dfdl:inputValueCalc="{ dfdlx:bitOr(xs:byte(1), xs:short(256)) }" />
+
</tdml:defineSchema>
<tdml:parserTestCase name="testIntOr" root="testIntOr" model="BitFunctions">
@@ -326,4 +338,35 @@
</tdml:dfdlInfoset>
</tdml:infoset>
</tdml:parserTestCase>
-</tdml:testSuite>
\ No newline at end of file
+
+ <tdml:parserTestCase name="testIntegerOr" root="testIntegerOr"
model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>xs:unsignedLong or xs:long or a subtype of those</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testNonNegativeIntegerOr"
root="testNonNegativeIntegerOr" model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>xs:unsignedLong or xs:long or a subtype of those</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testDifferentSignednessOr"
root="testDifferentSignednessOr" model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>must match in signedness</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testPromotionOr" root="testPromotionOr"
model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:testPromotionOr>257</ex:testPromotionOr>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+</tdml:testSuite>
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsXor.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsXor.tdml
index 3de29e387..b1683b406 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsXor.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/BitFunctionsXor.tdml
@@ -166,6 +166,18 @@
</xs:complexType>
</xs:element>
+ <xs:element name="testIntegerXor" type="xs:integer"
+ dfdl:inputValueCalc="{ dfdlx:bitXor(xs:integer(1), xs:long(1)) }" />
+
+ <xs:element name="testNonNegativeIntegerXor" type="xs:nonNegativeInteger"
+ dfdl:inputValueCalc="{ dfdlx:bitXor(xs:nonNegativeInteger(1),
xs:unsignedLong(1)) }" />
+
+ <xs:element name="testDifferentSignednessXor" type="xs:long"
+ dfdl:inputValueCalc="{ dfdlx:bitXor(xs:long(1), xs:unsignedLong(1)) }" />
+
+ <xs:element name="testPromotionXor" type="xs:long"
+ dfdl:inputValueCalc="{ dfdlx:bitXor(xs:byte(3), xs:short(257)) }" />
+
</tdml:defineSchema>
<tdml:parserTestCase name="testIntXor" root="testIntXor"
model="BitFunctions">
@@ -328,4 +340,35 @@
</tdml:dfdlInfoset>
</tdml:infoset>
</tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testIntegerXor" root="testIntegerXor"
model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>xs:unsignedLong or xs:long or a subtype of those</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testNonNegativeIntegerXor"
root="testNonNegativeIntegerXor" model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>xs:unsignedLong or xs:long or a subtype of those</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testDifferentSignednessXor"
root="testDifferentSignednessXor" model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:errors>
+ <tdml:error>must match in signedness</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="testPromotionXor" root="testPromotionXor"
model="BitFunctions">
+ <tdml:document></tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:testPromotionXor>258</ex:testPromotionXor>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
</tdml:testSuite>
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestBitFunctions.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestBitFunctions.scala
index 06a3d7759..8bb561c54 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestBitFunctions.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestBitFunctions.scala
@@ -84,6 +84,10 @@ class TestBitFunctionsXor extends TdmlTests {
@Test def testUnsignedLongXor = test
@Test def testUnsignedShortXor = test
@Test def testUnsignedByteXor = test
+ @Test def testIntegerXor = test
+ @Test def testNonNegativeIntegerXor = test
+ @Test def testDifferentSignednessXor = test
+ @Test def testPromotionXor = test
}
class TestBitFunctionsOr extends TdmlTests {
@@ -97,6 +101,10 @@ class TestBitFunctionsOr extends TdmlTests {
@Test def testUnsignedLongOr = test
@Test def testUnsignedShortOr = test
@Test def testUnsignedByteOr = test
+ @Test def testIntegerOr = test
+ @Test def testNonNegativeIntegerOr = test
+ @Test def testDifferentSignednessOr = test
+ @Test def testPromotionOr = test
}
class TestBitFunctionsAnd extends TdmlTests {
@@ -110,6 +118,10 @@ class TestBitFunctionsAnd extends TdmlTests {
@Test def testUnsignedLongAnd = test
@Test def testUnsignedShortAnd = test
@Test def testUnsignedByteAnd = test
+ @Test def testIntegerAnd = test
+ @Test def testNonNegativeIntegerAnd = test
+ @Test def testDifferentSignednessAnd = test
+ @Test def testPromotionAnd = test
}
class TestBitFunctionsNot extends TdmlTests {