stevedlawrence closed pull request #104: Make maxOccursBounds limit a fatal 
error
URL: https://github.com/apache/incubator-daffodil/pull/104
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/daffodil-cli/src/main/scala/org/apache/daffodil/Main.scala 
b/daffodil-cli/src/main/scala/org/apache/daffodil/Main.scala
index 451cdc100..0637cee5d 100644
--- a/daffodil-cli/src/main/scala/org/apache/daffodil/Main.scala
+++ b/daffodil-cli/src/main/scala/org/apache/daffodil/Main.scala
@@ -93,7 +93,6 @@ import javax.xml.transform.dom.DOMSource
 import javax.xml.transform.stream.StreamResult
 import javax.xml.parsers.DocumentBuilderFactory
 import org.apache.commons.io.IOUtils
-import org.apache.daffodil.api.TunableLimitExceededError
 import org.apache.daffodil.api.DaffodilTunables
 import org.apache.daffodil.io.InputSourceDataInputStream
 
@@ -1346,10 +1345,6 @@ object Main extends Logging {
         log(LogLevel.Error, "%s", e.getMessage())
         1
       }
-      case e: TunableLimitExceededError => {
-        log(LogLevel.Error, "%s", e.getMessage())
-        1
-      }
       case e: InvalidParserException => {
         log(LogLevel.Error, "%s", e.getMessage())
         1
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
index ac389cc6b..1373aa952 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
@@ -28,6 +28,7 @@ import org.apache.daffodil.dpath.NodeInfo.PrimType
 import org.apache.daffodil.dsom.ElementBase
 import org.apache.daffodil.dsom.ExpressionCompilers
 import org.apache.daffodil.dsom.InitiatedTerminatedMixin
+import org.apache.daffodil.dsom.TunableLimitExceededError
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.grammar.primitives.AlignmentFill
 import org.apache.daffodil.grammar.primitives.BCDDecimalDelimitedEndOfData
@@ -913,9 +914,9 @@ trait ElementBaseGrammarMixin
 
       case PrimType.Decimal => {
         if (binaryDecimalVirtualPoint > tunable.maxBinaryDecimalVirtualPoint)
-          SDE("Property binaryDecimalVirtualPoint %s is greater than limit 
%s", binaryDecimalVirtualPoint, tunable.maxBinaryDecimalVirtualPoint)
+          throw new TunableLimitExceededError(schemaFileLocation, "Property 
binaryDecimalVirtualPoint %s is greater than limit %s", 
binaryDecimalVirtualPoint, tunable.maxBinaryDecimalVirtualPoint)
         if (binaryDecimalVirtualPoint < tunable.minBinaryDecimalVirtualPoint)
-          SDE("Property binaryDecimalVirtualPoint %s is less than limit %s", 
binaryDecimalVirtualPoint, tunable.minBinaryDecimalVirtualPoint)
+          throw new TunableLimitExceededError(schemaFileLocation, "Property 
binaryDecimalVirtualPoint %s is less than limit %s", binaryDecimalVirtualPoint, 
tunable.minBinaryDecimalVirtualPoint)
         if (binaryNumberKnownLengthInBits == -1 ||
           binaryNumberKnownLengthInBits > 8) byteOrderRaw // must have or SDE
 
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesFraming.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesFraming.scala
index 300bc74e3..d22dfda83 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesFraming.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesFraming.scala
@@ -30,11 +30,14 @@ import 
org.apache.daffodil.processors.unparsers.MandatoryTextAlignmentUnparser
 import org.apache.daffodil.processors.unparsers.SkipRegionUnparser
 import org.apache.daffodil.processors.unparsers.Unparser
 import org.apache.daffodil.schema.annotation.props.gen.LengthKind
+import org.apache.daffodil.dsom.TunableLimitExceededError
 
 abstract class SkipRegion(e: Term, skipLengthInBits: Int, propName: String) 
extends Terminal(e, skipLengthInBits > 0) {
 
-  e.schemaDefinitionUnless(skipLengthInBits < e.tunable.maxSkipLengthInBytes * 
8,
-    "Property %s %s(bits) is larger than limit %s(bits).", propName, 
skipLengthInBits, e.tunable.maxSkipLengthInBytes * 8)
+  if (skipLengthInBits > e.tunable.maxSkipLengthInBytes * 8) {
+    throw new TunableLimitExceededError(e.schemaFileLocation,
+      "Property %s %s(bits) is larger than limit %s(bits).", propName, 
skipLengthInBits, e.tunable.maxSkipLengthInBytes * 8)
+  }
 
   final lazy val parser: Parser = new SkipRegionParser(skipLengthInBits, 
e.termRuntimeData)
   final lazy val unparser: Unparser = new SkipRegionUnparser(skipLengthInBits, 
e.termRuntimeData)
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/api/DaffodilTunables.scala 
b/daffodil-lib/src/main/scala/org/apache/daffodil/api/DaffodilTunables.scala
index 9ee58ba95..0f68c0b03 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/api/DaffodilTunables.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/api/DaffodilTunables.scala
@@ -89,7 +89,7 @@ case class DaffodilTunables(
   val maxFieldContentLengthInBytes: Long = 1024 * 1024, // Can be as large as 
Int.MaxValue
   val defaultInitRegexMatchLimitInChars: Long = 32,
   val maxDataDumpSizeInBytes: Long = 256,
-  val maxOccursBounds: Long = 1024, // Can be as large as Int.MaxValue
+  val maxOccursBounds: Long = Int.MaxValue, // Can be as large as Int.MaxValue
   //
   // When unexpected text is found where a delimiter is expected, this is the 
maximum
   // number of bytes (characters) to display when the expected delimiter is a 
variable
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/api/TunableLimitExceededError.scala
 
b/daffodil-lib/src/main/scala/org/apache/daffodil/api/TunableLimitExceededError.scala
deleted file mode 100644
index 9a18ea30f..000000000
--- 
a/daffodil-lib/src/main/scala/org/apache/daffodil/api/TunableLimitExceededError.scala
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.daffodil.api
-
-import org.apache.daffodil.util.Maybe._
-import org.apache.daffodil.util.Maybe
-
-/**
- * Exceeding these limits is not a back-trackable parse error. It's more severe
- * than that. But it is not a schema-definition error really either.
- */
-final class TunableLimitExceededError(limitName: String, cause: 
Option[Throwable], formatString: String, val args: Any*)
-  extends Diagnostic(Nope, Nope, cause, Maybe(formatString), args: _*) {
-
-  def isError = true
-  def modeName = "Tunable Limit"
-
-  def this(limitName: String, msg: String, args: Any*) = this(limitName, None, 
msg, args: _*)
-
-  def this(limitName: String, cause: Throwable) = this(limitName, Some(cause), 
"")
-
-}
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/SDE.scala 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/SDE.scala
index 0b4d6d426..569ad597c 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/SDE.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/SDE.scala
@@ -122,6 +122,19 @@ class ValidationError(schemaContext: 
Maybe[SchemaFileLocation],
 
 }
 
+final class TunableLimitExceededError(
+  annotationContext: SchemaFileLocation,
+  kind: String,
+  args: Any*)
+  extends SchemaDefinitionDiagnosticBase(
+    Maybe(annotationContext),
+    Nope, None, None,
+    Maybe(kind), args: _*) {
+
+  override def isError = true
+  override def modeName = "Tunable Limit Exceeded"
+}
+
 abstract class SchemaDefinitionDiagnosticBase(
   sc: Maybe[SchemaFileLocation],
   runtimeContext: Maybe[ParseOrUnparseState],
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Runtime.scala 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Runtime.scala
index 5e3a67eac..702ed2ba2 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Runtime.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Runtime.scala
@@ -59,7 +59,7 @@ import org.apache.daffodil.processors.parsers.ParseError
 import org.apache.daffodil.processors.parsers.Parser
 import org.apache.daffodil.processors.parsers.PState
 import org.apache.daffodil.exceptions.UnsuppressableException
-import org.apache.daffodil.api.TunableLimitExceededError
+import org.apache.daffodil.dsom.TunableLimitExceededError
 import org.apache.daffodil.api.DaffodilTunables
 
 /**
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
index a9ba90771..1aa084c64 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
@@ -21,6 +21,7 @@ import java.io.PrintWriter
 import org.apache.daffodil.exceptions.UnsuppressableException
 import java.io.StringWriter
 import org.apache.daffodil.dsom.SchemaDefinitionDiagnosticBase
+import org.apache.daffodil.dsom.TunableLimitExceededError
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.processors.Success
 import org.apache.daffodil.processors.SequenceRuntimeData
@@ -66,11 +67,12 @@ abstract class OrderedSequenceParserBase(
 
   protected def zeroLengthSpecialChecks(pstate: PState, 
wasLastChildZeroLength: Boolean): Unit
 
-  final protected def checkN(pstate: PState): Boolean = {
+  final protected def checkN(pstate: PState, childParser: 
RepeatingChildParser): Unit = {
     if (pstate.arrayPos > pstate.tunable.maxOccursBounds) {
-      PE(pstate, "Occurs count %s exceeds implementation maximum of %s.", 
pstate.arrayPos, pstate.tunable.maxOccursBounds)
-      false
-    } else true
+      throw new TunableLimitExceededError(childParser.erd.schemaFileLocation,
+        "Array occurrences excceeds the maxOccursBounds tunable limit of %s",
+        pstate.tunable.maxOccursBounds)
+    }
   }
 
   /**
@@ -139,11 +141,11 @@ abstract class OrderedSequenceParserBase(
                 //
                 val priorState = pstate.mark("before occurrence")
 
-                checkN(pstate) // check if arrayIndex exceeds tunable limit.
-
                 var markLeakCausedByException = false
                 var wasThrow = true
                 try {
+                  checkN(pstate, parser) // check if arrayIndex exceeds 
tunable limit.
+
                   pstate.pushDiscriminator
                   resultOfTry =
                     parseOneWithPoU(parser, erd, pstate, priorState, goAIS, 
isBounded)
@@ -281,7 +283,7 @@ abstract class OrderedSequenceParserBase(
                 }
               }) {
 
-                checkN(pstate)
+                checkN(pstate, parser)
                 resultOfTry = parseOneWithoutPoU(parser, parser.trd, pstate)
                 resultOfTry match {
                   case ParseAttemptStatus.Success_EndOfArray => // ok, success 
will move on to next sequence child.
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/tunables.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/tunables.tdml
index 826ec6e47..7472b9b42 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/tunables.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/tunables.tdml
@@ -43,6 +43,13 @@
                </daf:tunables>
        </tdml:defineConfig>
 
+       <tdml:defineConfig name="cfg_smallMaxOccursBounds">
+               <daf:tunables xmlns="http://www.w3.org/2001/XMLSchema";
+                       xmlns:xs="http://www.w3.org/2001/XMLSchema";>
+                       <daf:maxOccursBounds>3</daf:maxOccursBounds>
+               </daf:tunables>
+       </tdml:defineConfig>
+
        <tdml:defineSchema name="unqualifiedPathStep" 
elementFormDefault="unqualified">
                <xs:include 
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
 
@@ -178,4 +185,39 @@
                        </tdml:dfdlInfoset>
                </tdml:infoset>
        </tdml:parserTestCase>
+
+
+
+       <tdml:defineSchema name="exceedMaxOccursBounds">
+               <xs:include 
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
+
+               <dfdl:format ref="ex:GeneralFormat" />
+
+               <xs:element name="root">
+                       <xs:complexType>
+                               <xs:sequence>
+                                       <xs:element name="char" 
type="xs:string" maxOccurs="unbounded" dfdl:lengthKind="explicit" 
dfdl:length="1" />
+                               </xs:sequence>
+                       </xs:complexType>
+               </xs:element>
+       </tdml:defineSchema>
+
+       <tdml:parserTestCase
+               name="maxOccursBoundsExceeded" root="root"
+               model="exceedMaxOccursBounds" description="Tunables - 
maxOccursBounds"
+               config="cfg_smallMaxOccursBounds">
+
+               <tdml:document>
+                       <tdml:documentPart type="text">1234</tdml:documentPart>
+               </tdml:document>
+
+               <tdml:errors>
+                       <tdml:error>Tunable Limit Exceeded</tdml:error>
+                       <tdml:error>maxOccursBounds</tdml:error>
+                       <tdml:error>3</tdml:error>
+                       <tdml:error>char</tdml:error>
+               </tdml:errors>
+
+       </tdml:parserTestCase>
+
 </tdml:testSuite>
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 eb802561c..b9412249a 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
@@ -3048,7 +3048,7 @@
       <tdml:documentPart type="byte">00 00 00 01</tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>Schema Definition Error: Property binaryDecimalVirtualPoint 
201 is greater than limit 200</tdml:error>
+      <tdml:error>Tunable Limit Exceeded Error: Property 
binaryDecimalVirtualPoint 201 is greater than limit 200</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -3058,7 +3058,7 @@
       <tdml:documentPart type="byte">00 00 00 01</tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>Schema Definition Error: Property binaryDecimalVirtualPoint 
-201 is less than limit -200</tdml:error>
+      <tdml:error>Tunable Limit Exceeded Error: Property 
binaryDecimalVirtualPoint -201 is less than limit -200</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
index 0f9580cad..0f3f269bf 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
@@ -749,7 +749,7 @@
     <tdml:document />
 
     <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>Tunable Limit Exceeded Error</tdml:error>
       <tdml:error>Property leadingSkip</tdml:error>
       <tdml:error>is larger than limit</tdml:error>
     </tdml:errors>
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section00/general/TestGeneral.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section00/general/TestGeneral.scala
index be83052b4..41e6465f1 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section00/general/TestGeneral.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section00/general/TestGeneral.scala
@@ -99,5 +99,7 @@ class TestGeneral {
   @Test def test_unqualifiedPathStepPolicy_defaultNamespace_test_01() { 
tunables_runner.runOneTest("unqualifiedPathStepPolicy_defaultNamespace_test_01")
 }
   @Test def test_unqualifiedPathStepPolicy_noNamespace_test_02() { 
tunables_runner.runOneTest("unqualifiedPathStepPolicy_noNamespace_test_02") }
   @Test def test_unqualifiedPathStepPolicy_defaultNamespace_test_02() { 
tunables_runner.runOneTest("unqualifiedPathStepPolicy_defaultNamespace_test_02")
 }
+  
+  @Test def test_maxOccursBoundsExceeded() { 
tunables_runner.runOneTest("maxOccursBoundsExceeded") }
 
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to