From 829416d88e3992b6fb9dc436270e61bcba2bf474 Mon Sep 17 00:00:00 2001 From: jimingquan Date: Tue, 7 Sep 2021 16:39:07 +0800 Subject: [PATCH 1/2] add max allowed query size --- src/graph/service/GraphFlags.cpp | 1 + src/graph/validator/SequentialValidator.cpp | 6 ++++++ .../validator/test/QueryValidatorTest.cpp | 21 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/graph/service/GraphFlags.cpp b/src/graph/service/GraphFlags.cpp index 08e3164ae75..20e60daba8c 100644 --- a/src/graph/service/GraphFlags.cpp +++ b/src/graph/service/GraphFlags.cpp @@ -45,6 +45,7 @@ DEFINE_string(auth_type, DEFINE_string(cloud_http_url, "", "cloud http url including ip, port, url path"); DEFINE_uint32(max_allowed_statements, 512, "Max allowed sequential statements"); +DEFINE_uint32(max_allowed_query_size, 4194304, "Max allowed sequential query size"); DEFINE_int64(max_allowed_connections, std::numeric_limits::max(), diff --git a/src/graph/validator/SequentialValidator.cpp b/src/graph/validator/SequentialValidator.cpp index 61c12573df7..a31ad8b4de0 100644 --- a/src/graph/validator/SequentialValidator.cpp +++ b/src/graph/validator/SequentialValidator.cpp @@ -13,6 +13,7 @@ #include "graph/service/PermissionCheck.h" DECLARE_uint32(max_allowed_statements); +DECLARE_uint32(max_allowed_query_size); namespace nebula { namespace graph { @@ -24,6 +25,11 @@ Status SequentialValidator::validateImpl() { "given.", static_cast(sentence_->kind())); } + size_t querySize = sentence_->toString().size(); + size_t maxAllowedQuerySize = static_cast(FLAGS_max_allowed_query_size); + if (querySize > maxAllowedQuerySize) { + return Status::SemanticError("Query is too large (%ld > %ld).", querySize, maxAllowedQuerySize); + } auto seqSentence = static_cast(sentence_); auto sentences = seqSentence->sentences(); diff --git a/src/graph/validator/test/QueryValidatorTest.cpp b/src/graph/validator/test/QueryValidatorTest.cpp index 8593b17f55e..05463568e2b 100644 --- a/src/graph/validator/test/QueryValidatorTest.cpp +++ b/src/graph/validator/test/QueryValidatorTest.cpp @@ -8,6 +8,7 @@ #include "graph/validator/test/ValidatorTestBase.h" DECLARE_uint32(max_allowed_statements); +DECLARE_uint32(max_allowed_query_size); namespace nebula { namespace graph { @@ -1118,6 +1119,26 @@ TEST_F(QueryValidatorTest, TestMaxAllowedStatements) { "exceeded"); } +TEST_F(QueryValidatorTest, TestMaxAllowedQuerySize) { + FLAGS_max_allowed_query_size = 256; + std::string query = "INSERT VERTEX person(name, age) VALUES "; + std::string value = "\"person_1\":(\"person_1\", 1),"; + int count = (FLAGS_max_allowed_query_size - query.size()) / value.size(); + std::string values; + values.reserve(FLAGS_max_allowed_query_size); + for (int i = 0; i < count; ++i) { + values.append(value); + } + values.erase(values.size() - 1); + query += values; + EXPECT_TRUE(checkResult(query)); + query.append(",\"person_2\":(\"person_2\", 2);"); + auto result = checkResult(query); + EXPECT_FALSE(result); + EXPECT_EQ(std::string(result.message()), "SemanticError: Query is too large (271 > 256)."); + FLAGS_max_allowed_query_size = 4194304; +} + TEST_F(QueryValidatorTest, TestMatch) { { std::string query = From d2ceddff0bbea0151da6fba1840f15f436580621 Mon Sep 17 00:00:00 2001 From: jimingquan Date: Wed, 8 Sep 2021 17:48:41 +0800 Subject: [PATCH 2/2] address comment --- conf/nebula-graphd.conf.default | 2 ++ conf/nebula-graphd.conf.production | 2 ++ src/graph/validator/SequentialValidator.cpp | 6 ------ src/graph/validator/test/QueryValidatorTest.cpp | 2 +- src/parser/GQLParser.h | 9 +++++++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/conf/nebula-graphd.conf.default b/conf/nebula-graphd.conf.default index adee924bd85..9951cf37896 100644 --- a/conf/nebula-graphd.conf.default +++ b/conf/nebula-graphd.conf.default @@ -33,6 +33,8 @@ # Whether to treat partial success as an error. # This flag is only used for Read-only access, and Modify access always treats partial success as an error. --accept_partial_success=false +# Maximum sentence length, unit byte +--max_allowed_query_size=4194304 ########## networking ########## # Comma separated Meta Server Addresses diff --git a/conf/nebula-graphd.conf.production b/conf/nebula-graphd.conf.production index 6c4eeb96405..b3eebaf8dbf 100644 --- a/conf/nebula-graphd.conf.production +++ b/conf/nebula-graphd.conf.production @@ -31,6 +31,8 @@ # Whether to treat partial success as an error. # This flag is only used for Read-only access, and Modify access always treats partial success as an error. --accept_partial_success=false +# Maximum sentence length, unit byte +--max_allowed_query_size=4194304 ########## networking ########## # Comma separated Meta Server Addresses diff --git a/src/graph/validator/SequentialValidator.cpp b/src/graph/validator/SequentialValidator.cpp index a31ad8b4de0..61c12573df7 100644 --- a/src/graph/validator/SequentialValidator.cpp +++ b/src/graph/validator/SequentialValidator.cpp @@ -13,7 +13,6 @@ #include "graph/service/PermissionCheck.h" DECLARE_uint32(max_allowed_statements); -DECLARE_uint32(max_allowed_query_size); namespace nebula { namespace graph { @@ -25,11 +24,6 @@ Status SequentialValidator::validateImpl() { "given.", static_cast(sentence_->kind())); } - size_t querySize = sentence_->toString().size(); - size_t maxAllowedQuerySize = static_cast(FLAGS_max_allowed_query_size); - if (querySize > maxAllowedQuerySize) { - return Status::SemanticError("Query is too large (%ld > %ld).", querySize, maxAllowedQuerySize); - } auto seqSentence = static_cast(sentence_); auto sentences = seqSentence->sentences(); diff --git a/src/graph/validator/test/QueryValidatorTest.cpp b/src/graph/validator/test/QueryValidatorTest.cpp index 05463568e2b..025e3475f5a 100644 --- a/src/graph/validator/test/QueryValidatorTest.cpp +++ b/src/graph/validator/test/QueryValidatorTest.cpp @@ -1135,7 +1135,7 @@ TEST_F(QueryValidatorTest, TestMaxAllowedQuerySize) { query.append(",\"person_2\":(\"person_2\", 2);"); auto result = checkResult(query); EXPECT_FALSE(result); - EXPECT_EQ(std::string(result.message()), "SemanticError: Query is too large (271 > 256)."); + EXPECT_EQ(std::string(result.message()), "SyntaxError: Query is too large (282 > 256)."); FLAGS_max_allowed_query_size = 4194304; } diff --git a/src/parser/GQLParser.h b/src/parser/GQLParser.h index 10d1432d44c..d050fd71d27 100644 --- a/src/parser/GQLParser.h +++ b/src/parser/GQLParser.h @@ -11,6 +11,7 @@ #include "parser/GraphParser.hpp" #include "parser/GraphScanner.h" +DECLARE_uint32(max_allowed_query_size); namespace nebula { class GQLParser { @@ -39,8 +40,12 @@ class GQLParser { } StatusOr> parse(std::string query) { - // Since GraphScanner needs a writable buffer, we have to copy the query - // string + // Since GraphScanner needs a writable buffer, we have to copy the query string + size_t querySize = query.size(); + size_t maxAllowedQuerySize = static_cast(FLAGS_max_allowed_query_size); + if (querySize > maxAllowedQuerySize) { + return Status::SyntaxError("Query is too large (%ld > %ld).", querySize, maxAllowedQuerySize); + } buffer_ = std::move(query); pos_ = &buffer_[0]; end_ = pos_ + buffer_.size();