You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by sl...@apache.org on 2020/06/19 15:23:24 UTC

[incubator-daffodil] branch master updated: DAFFODIL-2349: fixed overflow ArithmeticException when totalDigits >= 10

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

slawrence pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git


The following commit(s) were added to refs/heads/master by this push:
     new 2d8eba2  DAFFODIL-2349: fixed overflow ArithmeticException when totalDigits >= 10
2d8eba2 is described below

commit 2d8eba2cd8dcb39c9d04ba530d92ec4ecb05f23b
Author: claude.mamo <cl...@gmail.com>
AuthorDate: Wed Jun 17 21:48:50 2020 +0200

    DAFFODIL-2349: fixed overflow ArithmeticException when totalDigits >= 10
    
    DAFFODIL-2349: computing the no. of digits from diNode instead of comparing diNode against powers of 10 ; added totalDigits test coverage for negative numbers; removed comma textNumberPattern in order to get the new unparse tests to pass
---
 .../apache/daffodil/processors/RuntimeData.scala   | 11 +++--
 .../apache/daffodil/section05/facets/Facets.tdml   | 53 +++++++++++++++++++++-
 .../daffodil/section05/facets/TestFacets.scala     |  3 ++
 3 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
index 07db069..3afca03 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
@@ -455,11 +455,12 @@ final class SimpleTypeRuntimeData(
     // Per http://www.w3.org/TR/xmlschema-2/#rf-totalDigits
     // |i| < 10^totalDigits
 
-    val number = new java.math.BigDecimal(scala.math.pow(10.0, digits.doubleValue()))
-    val biNumber = new java.math.BigInteger(number.intValueExact().toString())
-    val bdData = diNode.dataValueAsBigDecimal.unscaledValue()
-    val isDataLessThanNumber = bdData.compareTo(biNumber) < 0
-    isDataLessThanNumber
+    val bd = diNode.dataValueAsBigDecimal.stripTrailingZeros
+    val totalDigits =
+      if (bd.scale <= 0) bd.precision - bd.scale
+      else Math.max(bd.precision, bd.scale)
+    
+    totalDigits <= digits
   }
 
   private def checkFractionDigits(diNode: DISimple, digits: Long): Boolean = {
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/Facets.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/Facets.tdml
index 84aceae..1ac5385 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/Facets.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/Facets.tdml
@@ -3999,7 +3999,7 @@
         </xs:restriction>
       </xs:simpleType>
     </xs:element>
-    <xs:element name="e4_1_1" dfdl:lengthKind="delimited" dfdl:textNumberPattern="#,##0.#####;-#,##0.#####">
+    <xs:element name="e4_1_1" dfdl:lengthKind="delimited" dfdl:textNumberPattern="###0.#####;-###0.#####">
       <xs:annotation>
         <xs:appinfo source="http://www.ogf.org/dfdl/">
           <dfdl:assert test="{ dfdl:checkConstraints(.) }"
@@ -4513,6 +4513,17 @@
       </tdml:dfdlInfoset>
     </tdml:infoset>
   </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="test_totalDigits_Pass_Negative"
+                       root="e4_1_1" model="TestFacets">
+
+    <tdml:document>-12345</tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e4_1_1>-12345</e4_1_1>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>  
   
   <!--
     Test name: checkTotalDigits_Fail_Decimal
@@ -4527,6 +4538,15 @@
       <tdml:error>Assertion failed: Assertion failed for dfdl:checkConstraints(.)</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="test_totalDigits_Fail_Negative"
+                       root="e4_1_1" model="TestFacets">
+
+    <tdml:document>-123456</tdml:document>
+    <tdml:errors>
+      <tdml:error>Assertion failed: Assertion failed for dfdl:checkConstraints(.)</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
   
   <!--
     Test name: checkTotalDigitsFractionDigits_Pass
@@ -6499,6 +6519,25 @@
         </xs:restriction>
       </xs:simpleType>
     </xs:element>
+
+    <xs:simpleType name="tD_st10">
+      <xs:restriction base="xs:decimal">
+        <xs:totalDigits value="10" />
+      </xs:restriction>
+    </xs:simpleType>
+
+    <xs:element name="tD_e10" dfdl:lengthKind="delimited" dfdl:textNumberPattern="###0.#####;-###0.#####">
+      <xs:annotation>
+        <xs:appinfo source="http://www.ogf.org/dfdl/">
+          <dfdl:assert test="{ dfdl:checkConstraints(.) }"
+                       message="Assertion failed for dfdl:checkConstraints(.)" />
+        </xs:appinfo>
+      </xs:annotation>
+      <xs:simpleType>
+        <xs:restriction base="ex:tD_st10">
+        </xs:restriction>
+      </xs:simpleType>
+    </xs:element>
     
     <xs:element name="tD_e5" dfdl:representation="binary" dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="4">
       <xs:annotation>
@@ -6636,7 +6675,17 @@
         <tdml:error>totalDigits</tdml:error>
       </tdml:errors>
   </tdml:parserTestCase>
-  
+
+  <tdml:parserTestCase name="totalDigits10" root="tD_e10"
+                       model="totalDigitsSchema" description="Section 5 - Facets - totalDigits - DFDL-5-056R">
+    <tdml:document>9999999999</tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <tD_e10>9999999999</tD_e10>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
   <!--
     Test name: totalDigits04
     Schema: totalDigitsSchemaIsolate2 
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section05/facets/TestFacets.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section05/facets/TestFacets.scala
index c9cf76e..a441ee7 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section05/facets/TestFacets.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section05/facets/TestFacets.scala
@@ -205,7 +205,9 @@ class TestFacets {
 
   @Test def test_testBinary(): Unit = { runner.runOneTest("testBinary") }
   @Test def test_totalDigits_Pass_Decimal: Unit = { runner.runOneTest("checkTotalDigits_Pass_Decimal") }
+  @Test def test_totalDigits_Pass_Negative: Unit = { runner.runOneTest("test_totalDigits_Pass_Negative") }
   @Test def test_totalDigits_Fail_Decimal: Unit = { runner.runOneTest("checkTotalDigits_Fail_Decimal") }
+  @Test def test_totalDigits_Fail_Negative: Unit = { runner.runOneTest("test_totalDigits_Fail_Negative") }
   @Test def test_fractionDigits_Pass: Unit = { runner.runOneTest("checkFractionDigits_Pass") }
   @Test def test_fractionDigits_Fail: Unit = { runner.runOneTest("checkFractionDigits_Fail") }
   @Test def test_fractionDigits_Pass_LessDigits: Unit = { runner.runOneTest("checkFractionDigits_Pass_LessDigits") }
@@ -224,6 +226,7 @@ class TestFacets {
 
   @Test def test_totalDigits05b(): Unit = { runner.runOneTest("totalDigits05b") }
   @Test def test_totalDigits09(): Unit = { runnerV.runOneTest("totalDigits09") }
+  @Test def test_totalDigits10(): Unit = { runnerV.runOneTest("totalDigits10") }
 
   @Test def test_patternRegexDFDL708_01(): Unit = { runner.runOneTest("patternRegexDFDL708_01") }
   @Test def test_patternRegexDFDL708_02(): Unit = { runner.runOneTest("patternRegexDFDL708_02") }