Skip to content

Commit

Permalink
DAFFODIL-2349: fixed overflow ArithmeticException when totalDigits >= 10
Browse files Browse the repository at this point in the history
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
  • Loading branch information
cjmamo authored and stevedlawrence committed Jun 19, 2020
1 parent c9ca5d6 commit 2d8eba2
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(.) }"
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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") }
Expand All @@ -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") }
Expand Down

0 comments on commit 2d8eba2

Please sign in to comment.