aboutsummaryrefslogtreecommitdiffstats
path: root/document/src/tests/documentselectparsertest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'document/src/tests/documentselectparsertest.cpp')
-rw-r--r--document/src/tests/documentselectparsertest.cpp68
1 files changed, 59 insertions, 9 deletions
diff --git a/document/src/tests/documentselectparsertest.cpp b/document/src/tests/documentselectparsertest.cpp
index 110153954af..c8cbd1be9c2 100644
--- a/document/src/tests/documentselectparsertest.cpp
+++ b/document/src/tests/documentselectparsertest.cpp
@@ -18,6 +18,7 @@
#include <vespa/document/select/compare.h>
#include <vespa/document/select/operator.h>
#include <vespa/document/select/parse_utils.h>
+#include <vespa/document/select/parser_limits.h>
#include <vespa/vespalib/util/exceptions.h>
#include <limits>
#include <gtest/gtest.h>
@@ -1247,17 +1248,17 @@ TEST_F(DocumentSelectParserTest, testThatSimpleFieldValuesHaveCorrectFieldName)
TEST_F(DocumentSelectParserTest, testThatComplexFieldValuesHaveCorrectFieldNames)
{
- EXPECT_EQ(
- vespalib::string("headerval"),
- parseFieldValue("testdoctype1.headerval{test}")->getRealFieldName());
+ EXPECT_EQ(vespalib::string("headerval"),
+ parseFieldValue("testdoctype1.headerval{test}")->getRealFieldName());
- EXPECT_EQ(
- vespalib::string("headerval"),
- parseFieldValue("testdoctype1.headerval[42]")->getRealFieldName());
+ EXPECT_EQ(vespalib::string("headerval"),
+ parseFieldValue("testdoctype1.headerval[42]")->getRealFieldName());
- EXPECT_EQ(
- vespalib::string("headerval"),
- parseFieldValue("testdoctype1.headerval.meow.meow{test}")->getRealFieldName());
+ EXPECT_EQ(vespalib::string("headerval"),
+ parseFieldValue("testdoctype1.headerval.meow.meow{test}")->getRealFieldName());
+
+ EXPECT_EQ(vespalib::string("headerval"),
+ parseFieldValue("testdoctype1.headerval .meow.meow{test}")->getRealFieldName());
}
namespace {
@@ -1603,4 +1604,53 @@ TEST_F(DocumentSelectParserTest, redundant_glob_wildcards_are_collapsed_into_min
EXPECT_EQ(GlobOperator::convertToRegex("*?*?*?*"), "..*..*."); // Don't try this at home, kids!
}
+TEST_F(DocumentSelectParserTest, recursion_depth_is_bounded_for_field_exprs) {
+ createDocs();
+ std::string expr = "testdoctype1";
+ for (size_t i = 0; i < 50000; ++i) {
+ expr += ".foo";
+ }
+ expr += ".hash() != 0";
+ verifyFailedParse(expr, "ParsingFailedException: expression is too deeply nested");
+}
+
+TEST_F(DocumentSelectParserTest, recursion_depth_is_bounded_for_arithmetic_exprs) {
+ createDocs();
+ std::string expr = "1";
+ for (size_t i = 0; i < 50000; ++i) {
+ expr += "+1";
+ }
+ expr += " != 0";
+ verifyFailedParse(expr, "ParsingFailedException: expression is too deeply nested");
+}
+
+TEST_F(DocumentSelectParserTest, recursion_depth_is_bounded_for_binary_logical_exprs) {
+ createDocs();
+ // Also throw in some comparisons to ensure they carry over the max depth.
+ std::string expr = "1 == 2";
+ std::string cmp_subexpr = "3 != 4";
+ for (size_t i = 0; i < 10000; ++i) {
+ expr += (i % 2 == 0 ? " and " : " or ") + cmp_subexpr;
+ }
+ verifyFailedParse(expr, "ParsingFailedException: expression is too deeply nested");
+}
+
+TEST_F(DocumentSelectParserTest, recursion_depth_is_bounded_for_unary_logical_exprs) {
+ createDocs();
+ std::string expr;
+ for (size_t i = 0; i < 10000; ++i) {
+ expr += "not ";
+ }
+ expr += "true";
+ verifyFailedParse(expr, "ParsingFailedException: expression is too deeply nested");
+}
+
+TEST_F(DocumentSelectParserTest, selection_has_upper_limit_on_input_size) {
+ createDocs();
+ std::string expr = ("testdoctype1.a_biii"
+ + std::string(select::ParserLimits::MaxSelectionByteSize, 'i')
+ + "iiig_identifier");
+ verifyFailedParse(expr, "ParsingFailedException: expression is too large to be parsed");
+}
+
} // document