Skip to content

Commit

Permalink
fix crash when the expression exceed the depth (#3606)
Browse files Browse the repository at this point in the history
  • Loading branch information
heroicNeZha authored and Sophie-Xie committed Jan 10, 2022
1 parent c830ce0 commit b2f0271
Show file tree
Hide file tree
Showing 5 changed files with 424 additions and 67 deletions.
180 changes: 180 additions & 0 deletions src/graph/util/ExpressionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
#include "graph/util/ExpressionUtils.h"

#include <memory>
#include <queue>

#include "common/base/ObjectPool.h"
#include "common/expression/Expression.h"
#include "common/expression/PropertyExpression.h"
#include "common/function/AggFunctionManager.h"
#include "graph/context/QueryContext.h"
Expand Down Expand Up @@ -984,5 +986,183 @@ bool ExpressionUtils::isGeoIndexAcceleratedPredicate(const Expression *expr) {
return false;
}

bool ExpressionUtils::checkExprDepth(const Expression *expr) {
std::queue<const Expression *> exprQueue;
exprQueue.emplace(expr);
int depth = 0;
while (!exprQueue.empty()) {
int size = exprQueue.size();
while (size > 0) {
const Expression *cur = exprQueue.front();
exprQueue.pop();
switch (cur->kind()) {
case Expression::Kind::kConstant:
case Expression::Kind::kVar: {
break;
}
case Expression::Kind::kAdd:
case Expression::Kind::kMinus:
case Expression::Kind::kMultiply:
case Expression::Kind::kDivision:
case Expression::Kind::kMod: {
auto *ariExpr = static_cast<const ArithmeticExpression *>(cur);
exprQueue.emplace(ariExpr->left());
exprQueue.emplace(ariExpr->right());
break;
}
case Expression::Kind::kIsNull:
case Expression::Kind::kIsNotNull:
case Expression::Kind::kIsEmpty:
case Expression::Kind::kIsNotEmpty:
case Expression::Kind::kUnaryPlus:
case Expression::Kind::kUnaryNegate:
case Expression::Kind::kUnaryNot:
case Expression::Kind::kUnaryIncr:
case Expression::Kind::kUnaryDecr: {
auto *unaExpr = static_cast<const UnaryExpression *>(cur);
exprQueue.emplace(unaExpr->operand());
break;
}
case Expression::Kind::kRelEQ:
case Expression::Kind::kRelNE:
case Expression::Kind::kRelLT:
case Expression::Kind::kRelLE:
case Expression::Kind::kRelGT:
case Expression::Kind::kRelGE:
case Expression::Kind::kRelREG:
case Expression::Kind::kContains:
case Expression::Kind::kNotContains:
case Expression::Kind::kStartsWith:
case Expression::Kind::kNotStartsWith:
case Expression::Kind::kEndsWith:
case Expression::Kind::kNotEndsWith:
case Expression::Kind::kRelNotIn:
case Expression::Kind::kRelIn: {
auto *relExpr = static_cast<const RelationalExpression *>(cur);
exprQueue.emplace(relExpr->left());
exprQueue.emplace(relExpr->right());
break;
}
case Expression::Kind::kList: {
auto *listExpr = static_cast<const ListExpression *>(cur);
for (auto &item : listExpr->items()) {
exprQueue.emplace(item);
}
break;
}
case Expression::Kind::kSet: {
auto *setExpr = static_cast<const SetExpression *>(cur);
for (auto &item : setExpr->items()) {
exprQueue.emplace(item);
}
break;
}
case Expression::Kind::kMap: {
auto *mapExpr = static_cast<const MapExpression *>(cur);
for (auto &item : mapExpr->items()) {
exprQueue.emplace(item.second);
}
break;
}
case Expression::Kind::kCase: {
auto *caseExpr = static_cast<const CaseExpression *>(cur);
if (caseExpr->hasCondition()) {
exprQueue.emplace(caseExpr->condition());
}
if (caseExpr->hasDefault()) {
exprQueue.emplace(caseExpr->defaultResult());
}
for (auto &whenThen : caseExpr->cases()) {
exprQueue.emplace(whenThen.when);
exprQueue.emplace(whenThen.then);
}
break;
}
case Expression::Kind::kListComprehension: {
auto *lcExpr = static_cast<const ListComprehensionExpression *>(cur);
exprQueue.emplace(lcExpr->collection());
if (lcExpr->hasFilter()) {
exprQueue.emplace(lcExpr->filter());
}
if (lcExpr->hasMapping()) {
exprQueue.emplace(lcExpr->mapping());
}
break;
}
case Expression::Kind::kPredicate: {
auto *predExpr = static_cast<const PredicateExpression *>(cur);
exprQueue.emplace(predExpr->collection());
if (predExpr->hasFilter()) {
exprQueue.emplace(predExpr->filter());
}
break;
}
case Expression::Kind::kReduce: {
auto *reduceExpr = static_cast<const ReduceExpression *>(cur);
exprQueue.emplace(reduceExpr->collection());
exprQueue.emplace(reduceExpr->mapping());
break;
}
case Expression::Kind::kLogicalAnd:
case Expression::Kind::kLogicalOr:
case Expression::Kind::kLogicalXor: {
auto *logExpr = static_cast<const LogicalExpression *>(cur);
for (auto &op : logExpr->operands()) {
exprQueue.emplace(op);
}
break;
}
case Expression::Kind::kTypeCasting: {
auto *typExpr = static_cast<const TypeCastingExpression *>(cur);
exprQueue.emplace(typExpr->operand());
break;
}
case Expression::Kind::kFunctionCall: {
auto *funExpr = static_cast<const FunctionCallExpression *>(cur);
auto &args = funExpr->args()->args();
for (auto iter = args.begin(); iter < args.end(); ++iter) {
exprQueue.emplace(*iter);
}
break;
}
case Expression::Kind::kTagProperty:
case Expression::Kind::kSrcProperty:
case Expression::Kind::kEdgeRank:
case Expression::Kind::kEdgeDst:
case Expression::Kind::kEdgeSrc:
case Expression::Kind::kEdgeType:
case Expression::Kind::kEdgeProperty:
case Expression::Kind::kInputProperty:
case Expression::Kind::kSubscript:
case Expression::Kind::kAttribute:
case Expression::Kind::kLabelAttribute:
case Expression::Kind::kVertex:
case Expression::Kind::kEdge:
case Expression::Kind::kLabel:
case Expression::Kind::kVarProperty:
case Expression::Kind::kDstProperty:
case Expression::Kind::kUUID:
case Expression::Kind::kPathBuild:
case Expression::Kind::kColumn:
case Expression::Kind::kTSPrefix:
case Expression::Kind::kTSWildcard:
case Expression::Kind::kTSRegexp:
case Expression::Kind::kTSFuzzy:
case Expression::Kind::kAggregate:
case Expression::Kind::kSubscriptRange:
case Expression::Kind::kVersionedVar:
default:
break;
}
size -= 1;
}
depth += 1;
if (depth > ExpressionUtils::kMaxDepth) {
return false;
}
}
return true;
} // namespace graph

} // namespace graph
} // namespace nebula
4 changes: 4 additions & 0 deletions src/graph/util/ExpressionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ class ExpressionUtils {

// TODO(jie) Move it to a better place
static bool isGeoIndexAcceleratedPredicate(const Expression* expr);

static bool checkExprDepth(const Expression* expr);

static constexpr int32_t kMaxDepth = 512;
};

} // namespace graph
Expand Down
Loading

0 comments on commit b2f0271

Please sign in to comment.