add sql wall support

This commit is contained in:
温少
2012-03-15 08:01:41 +08:00
parent d42e9cc807
commit a294ed7a1d
4 changed files with 83 additions and 18 deletions
@@ -8,6 +8,7 @@ import com.alibaba.druid.filter.wall.Violation;
import com.alibaba.druid.filter.wall.WallVisitor;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
@@ -74,4 +75,9 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
public boolean visit(MySqlSelectQueryBlock x) {
return visit((SQLSelectQueryBlock) x);
}
public boolean visit(SQLDropTableStatement x) {
violations.add(new IllegalStatementViolation(SQLUtils.toMySqlString(x)));
return false;
}
}
@@ -3,9 +3,12 @@ package com.alibaba.druid.filter.wall.spi;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.filter.wall.IllegalStatementViolation;
import com.alibaba.druid.filter.wall.Violation;
import com.alibaba.druid.filter.wall.WallVisitor;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVIsitorAdapter;
public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVisitor {
@@ -29,4 +32,9 @@ public class OracleWallVisitor extends OracleASTVIsitorAdapter implements WallVi
return true;
}
public boolean visit(SQLDropTableStatement x) {
violations.add(new IllegalStatementViolation(SQLUtils.toOracleString(x)));
return false;
}
}
@@ -4,12 +4,19 @@ import com.alibaba.druid.filter.wall.IllegalConditionViolation;
import com.alibaba.druid.filter.wall.WallVisitor;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLNotExpr;
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
public class WallVisitorUtils {
@@ -42,82 +49,82 @@ public class WallVisitorUtils {
return true;
}
}
if (x.getOperator() == SQLBinaryOperator.Equality) {
if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) {
return true;
}
if (leftResult == null || rightResult == null) {
return null;
}
return leftResult.equals(rightResult);
}
if (x.getOperator() == SQLBinaryOperator.NotEqual || x.getOperator() == SQLBinaryOperator.LessThanOrGreater) {
if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) {
return false;
}
if (leftResult == null || rightResult == null) {
return null;
}
return !leftResult.equals(rightResult);
}
if (x.getOperator() == SQLBinaryOperator.GreaterThan) {
if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) {
return false;
}
if (leftResult == null || rightResult == null) {
return null;
}
if (leftResult instanceof Comparable) {
return (((Comparable) leftResult).compareTo(rightResult) > 0);
}
}
if (x.getOperator() == SQLBinaryOperator.GreaterThanOrEqual) {
if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) {
return false;
}
if (leftResult == null || rightResult == null) {
return null;
}
if (leftResult instanceof Comparable) {
return ((Comparable) leftResult).compareTo(rightResult) >= 0;
}
}
if (x.getOperator() == SQLBinaryOperator.LessThan) {
if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) {
return false;
}
if (leftResult == null || rightResult == null) {
return null;
}
if (leftResult instanceof Comparable) {
return (((Comparable) leftResult).compareTo(rightResult) < 0);
}
}
if (x.getOperator() == SQLBinaryOperator.LessThanOrEqual) {
if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) {
return false;
}
if (leftResult == null || rightResult == null) {
return null;
}
if (leftResult instanceof Comparable) {
return ((Comparable) leftResult).compareTo(rightResult) <= 0;
}
@@ -162,7 +169,48 @@ public class WallVisitorUtils {
return !((Boolean) result).booleanValue();
}
}
if (x instanceof SQLQueryExpr) {
if (isSimpleCountTableSource(((SQLQueryExpr) x).getSubQuery())) {
return Integer.valueOf(1);
}
}
return null;
}
public static boolean isSimpleCountTableSource(SQLTableSource tableSource) {
if (!(tableSource instanceof SQLSubqueryTableSource)) {
return false;
}
SQLSubqueryTableSource subQuery = (SQLSubqueryTableSource) tableSource;
return isSimpleCountTableSource(subQuery.getSelect());
}
public static boolean isSimpleCountTableSource(SQLSelect select) {
SQLSelectQuery query = select.getQuery();
if (query instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
boolean allawTrueWhere = queryBlock.getWhere() == null || getValue(queryBlock.getWhere()) == Boolean.TRUE;
boolean simpleCount = false;
if (queryBlock.getSelectList().size() == 1) {
SQLExpr selectItemExpr = queryBlock.getSelectList().get(0).getExpr();
if (selectItemExpr instanceof SQLAggregateExpr) {
if (((SQLAggregateExpr) selectItemExpr).getMethodName().equalsIgnoreCase("COUNT")) {
simpleCount = true;
}
}
}
if (allawTrueWhere && simpleCount) {
return true;
}
}
return false;
}
}