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