add sql wall support

This commit is contained in:
温少
2012-03-14 23:56:58 +08:00
parent 9707e2fb23
commit cc8d00d78d
4 changed files with 134 additions and 37 deletions
@@ -3,12 +3,17 @@ 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.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTablesStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisitor {
@@ -28,6 +33,25 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
}
public boolean visit(MySqlExecuteStatement x) {
violations.add(new IllegalStatementViolation(SQLUtils.toMySqlString(x)));
return false;
}
@Override
public boolean visit(MySqlShowTablesStatement x) {
violations.add(new IllegalStatementViolation(SQLUtils.toMySqlString(x)));
return false;
}
@Override
public boolean visit(MySqlShowDatabasesStatement x) {
violations.add(new IllegalStatementViolation(SQLUtils.toMySqlString(x)));
return false;
}
@Override
public boolean visit(MySqlShowColumnsStatement x) {
violations.add(new IllegalStatementViolation(SQLUtils.toMySqlString(x)));
return false;
}
@@ -7,8 +7,9 @@ import com.alibaba.druid.sql.ast.SQLExpr;
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.SQLLiteralExpr;
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.dialect.mysql.ast.expr.MySqlBooleanExpr;
public class WallVisitorUtils {
@@ -19,20 +20,106 @@ public class WallVisitorUtils {
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Object getObject(SQLBinaryOpExpr x) {
if (x.getLeft() instanceof SQLLiteralExpr && x.getRight() instanceof SQLLiteralExpr) {
if (x.getOperator() == SQLBinaryOperator.Equality) {
String leftLiteral = SQLUtils.toOracleString(x.getLeft());
String rightLiteral = SQLUtils.toOracleString(x.getRight());
x.getLeft().setParent(x);
x.getRight().setParent(x);
Object leftResult = getValue(x.getLeft());
Object rightResult = getValue(x.getRight());
return leftLiteral.equalsIgnoreCase(rightLiteral);
if (x.getOperator() == SQLBinaryOperator.BooleanOr) {
if (Boolean.TRUE == leftResult || Boolean.TRUE == rightResult) {
return true;
}
}
if (x.getOperator() == SQLBinaryOperator.BooleanAnd) {
if (Boolean.FALSE == leftResult || Boolean.FALSE == rightResult) {
return false;
}
if (x.getOperator() == SQLBinaryOperator.NotEqual || x.getOperator() == SQLBinaryOperator.LessThanOrGreater) {
String leftLiteral = SQLUtils.toSQLString(x.getLeft());
String rightLiteral = SQLUtils.toSQLString(x.getRight());
return !leftLiteral.equalsIgnoreCase(rightLiteral);
if (Boolean.TRUE == leftResult && Boolean.TRUE == rightResult) {
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;
}
}
@@ -53,31 +140,6 @@ public class WallVisitorUtils {
}
}
x.getLeft().setParent(x);
x.getRight().setParent(x);
if (x.getOperator() == SQLBinaryOperator.BooleanOr) {
Object leftResult = getValue(x.getLeft());
Object rightResult = getValue(x.getRight());
if (Boolean.TRUE == leftResult || Boolean.TRUE == rightResult) {
return true;
}
}
if (x.getOperator() == SQLBinaryOperator.BooleanAnd) {
Object leftResult = getValue(x.getLeft());
Object rightResult = getValue(x.getRight());
if (Boolean.FALSE == leftResult || Boolean.FALSE == rightResult) {
return false;
}
if (Boolean.TRUE == leftResult && Boolean.TRUE == rightResult) {
return true;
}
}
return null;
}
@@ -90,6 +152,10 @@ public class WallVisitorUtils {
return ((MySqlBooleanExpr) x).getValue();
}
if (x instanceof SQLNumericLiteralExpr) {
return ((SQLNumericLiteralExpr) x).getNumber();
}
if (x instanceof SQLNotExpr) {
Object result = getValue(((SQLNotExpr) x).getExpr());
if (result != null && result instanceof Boolean) {
@@ -13,6 +13,7 @@ import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.Token;
@@ -116,7 +117,7 @@ public class SQLUtils {
}
public static SQLExpr toSQLExpr(String sql) {
MySqlLexer lexer = new MySqlLexer(sql);
Lexer lexer = new Lexer(sql);
lexer.nextToken();
SQLExprParser parser = new SQLExprParser(lexer);
@@ -20,5 +20,11 @@ public class WallVisitorUtilsTest extends TestCase {
Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("a1 = b1 OR f1 like '%%'")));
Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("1 < 2")));
Assert.assertEquals(Boolean.FALSE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("2 < 2")));
Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("2 <= 2")));
Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("2 > 1")));
Assert.assertEquals(Boolean.FALSE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("2 > 2")));
Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("2 >= 2")));
}
}