improve WallFilter

This commit is contained in:
wenshao
2013-03-18 21:28:35 +08:00
parent 0163cb488a
commit 434b11695a
12 changed files with 227 additions and 233 deletions
@@ -118,7 +118,9 @@ public class SQLEvalVisitorUtils {
}
public static boolean visit(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
if ("concat".equalsIgnoreCase(x.getMethodName())) {
String methodName = x.getMethodName().toLowerCase();
if ("concat".equals(methodName)) {
StringBuilder buf = new StringBuilder();
for (SQLExpr item : x.getParameters()) {
@@ -132,9 +134,9 @@ public class SQLEvalVisitorUtils {
}
x.getAttributes().put(EVAL_VALUE, buf.toString());
} else if ("now".equalsIgnoreCase(x.getMethodName())) {
} else if ("now".equals(methodName)) {
x.getAttributes().put(EVAL_VALUE, new Date());
} else if ("ascii".equalsIgnoreCase(x.getMethodName())) {
} else if ("ascii".equals(methodName)) {
if (x.getParameters().size() == 0) {
return false;
}
@@ -153,7 +155,7 @@ public class SQLEvalVisitorUtils {
int ascii = strValue.charAt(0);
x.getAttributes().put(EVAL_VALUE, ascii);
} else if ("instr".equalsIgnoreCase(x.getMethodName())) {
} else if ("instr".equals(methodName)) {
if (x.getParameters().size() != 2) {
return false;
}
@@ -175,7 +177,7 @@ public class SQLEvalVisitorUtils {
int result = strValue0.indexOf(strValue1) + 1;
x.putAttribute(EVAL_VALUE, result);
} else if ("left".equalsIgnoreCase(x.getMethodName())) {
} else if ("left".equals(methodName)) {
if (x.getParameters().size() != 2) {
return false;
}
@@ -197,7 +199,7 @@ public class SQLEvalVisitorUtils {
String result = strValue.substring(0, intValue);
x.putAttribute(EVAL_VALUE, result);
} else if ("right".equalsIgnoreCase(x.getMethodName())) {
} else if ("right".equals(methodName)) {
if (x.getParameters().size() != 2) {
return false;
}
@@ -219,7 +221,7 @@ public class SQLEvalVisitorUtils {
String result = strValue.substring(strValue.length() - intValue, strValue.length());
x.putAttribute(EVAL_VALUE, result);
} else if ("reverse".equalsIgnoreCase(x.getMethodName())) {
} else if ("reverse".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -241,7 +243,7 @@ public class SQLEvalVisitorUtils {
String result = buf.toString();
x.putAttribute(EVAL_VALUE, result);
} else if ("trim".equalsIgnoreCase(x.getMethodName())) {
} else if ("trim".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -258,7 +260,7 @@ public class SQLEvalVisitorUtils {
String result = strValue.trim();
x.putAttribute(EVAL_VALUE, result);
} else if ("length".equalsIgnoreCase(x.getMethodName())) {
} else if ("length".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -276,7 +278,7 @@ public class SQLEvalVisitorUtils {
int result = strValue.length();
x.putAttribute(EVAL_VALUE, result);
} else if ("ucase".equalsIgnoreCase(x.getMethodName()) || "upper".equalsIgnoreCase(x.getMethodName())) {
} else if ("ucase".equals(methodName) || "upper".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -294,7 +296,7 @@ public class SQLEvalVisitorUtils {
String result = strValue.toUpperCase();
x.putAttribute(EVAL_VALUE, result);
} else if ("lcase".equalsIgnoreCase(x.getMethodName()) || "lower".equalsIgnoreCase(x.getMethodName())) {
} else if ("lcase".equals(methodName) || "lower".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -313,7 +315,7 @@ public class SQLEvalVisitorUtils {
x.putAttribute(EVAL_VALUE, result);
} else if ("mod".equalsIgnoreCase(x.getMethodName())) {
} else if ("mod".equals(methodName)) {
if (x.getParameters().size() != 2) {
return false;
}
@@ -335,7 +337,7 @@ public class SQLEvalVisitorUtils {
int result = intValue0 % intValue1;
x.putAttribute(EVAL_VALUE, result);
} else if ("abs".equalsIgnoreCase(x.getMethodName())) {
} else if ("abs".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -358,7 +360,7 @@ public class SQLEvalVisitorUtils {
}
x.putAttribute(EVAL_VALUE, result);
} else if ("acos".equalsIgnoreCase(x.getMethodName())) {
} else if ("acos".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -379,7 +381,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("asin".equalsIgnoreCase(x.getMethodName())) {
} else if ("asin".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -400,7 +402,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("atan".equalsIgnoreCase(x.getMethodName())) {
} else if ("atan".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -421,7 +423,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("atan2".equalsIgnoreCase(x.getMethodName())) {
} else if ("atan2".equals(methodName)) {
if (x.getParameters().size() != 2) {
return false;
}
@@ -446,7 +448,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("ceil".equalsIgnoreCase(x.getMethodName()) || "ceiling".equalsIgnoreCase(x.getMethodName())) {
} else if ("ceil".equals(methodName) || "ceiling".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -467,7 +469,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("cos".equalsIgnoreCase(x.getMethodName())) {
} else if ("cos".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -488,7 +490,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("sin".equalsIgnoreCase(x.getMethodName())) {
} else if ("sin".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -509,7 +511,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("log".equalsIgnoreCase(x.getMethodName())) {
} else if ("log".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -530,7 +532,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("log10".equalsIgnoreCase(x.getMethodName())) {
} else if ("log10".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -551,7 +553,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("tan".equalsIgnoreCase(x.getMethodName())) {
} else if ("tan".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -572,7 +574,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("sqrt".equalsIgnoreCase(x.getMethodName())) {
} else if ("sqrt".equals(methodName)) {
if (x.getParameters().size() != 1) {
return false;
}
@@ -593,7 +595,7 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("power".equalsIgnoreCase(x.getMethodName())) {
} else if ("power".equals(methodName)) {
if (x.getParameters().size() != 2) {
return false;
}
@@ -618,10 +620,18 @@ public class SQLEvalVisitorUtils {
} else {
x.putAttribute(EVAL_VALUE, result);
}
} else if ("pi".equalsIgnoreCase(x.getMethodName())) {
} else if ("pi".equals(methodName)) {
x.putAttribute(EVAL_VALUE, Math.PI);
} else if ("rand".equalsIgnoreCase(x.getMethodName())) {
} else if ("rand".equals(methodName)) {
x.putAttribute(EVAL_VALUE, Math.random());
} else if ("chr".equals(methodName) && x.getParameters().size() == 1) {
SQLExpr first = x.getParameters().get(0);
Object firstResult = getValue(first);
if (firstResult instanceof Number) {
int intValue = ((Number) firstResult).intValue();
char ch = (char) intValue;
x.putAttribute(EVAL_VALUE, Character.toString(ch));
}
}
return false;
}
@@ -790,11 +800,11 @@ public class SQLEvalVisitorUtils {
left.accept(visitor);
right.accept(visitor);
final WallConditionContext wallConditionContext = WallVisitorUtils.getWallConditionContext();
if (x.getOperator() == SQLBinaryOperator.BooleanOr) {
final WallConditionContext wallContext = WallVisitorUtils.getWallConditionContext();
if (wallContext != null) {
if (wallConditionContext != null) {
if (left.getAttribute(EVAL_VALUE) == Boolean.TRUE || right.getAttribute(EVAL_VALUE) == Boolean.TRUE) {
wallContext.setPartAllowTrue(true);
wallConditionContext.setPartAlwayTrue(true);
}
}
}
@@ -807,52 +817,68 @@ public class SQLEvalVisitorUtils {
return false;
}
if (wallConditionContext != null) {
switch (x.getOperator()) {
case Add:
case Subtract:
case Multiply:
case Divide:
case Modulus:
wallConditionContext.setConstArithmetic(true);
break;
default:
break;
}
}
Object value = null;
Object leftValue = left.getAttribute(EVAL_VALUE);
Object rightValue = right.getAttributes().get(EVAL_VALUE);
switch (x.getOperator()) {
case Add:
value = add(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = add(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case Subtract:
value = sub(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = sub(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case Multiply:
value = multi(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = multi(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case Divide:
value = div(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = div(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case GreaterThan:
value = gt(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = gt(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case GreaterThanOrEqual:
value = gteq(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = gteq(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case LessThan:
value = lt(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = lt(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case LessThanOrEqual:
value = lteq(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = lteq(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case Is:
case Equality:
value = eq(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = eq(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case IsNot:
value = !eq(left.getAttribute(EVAL_VALUE), right.getAttributes().get(EVAL_VALUE));
value = !eq(leftValue, rightValue);
x.putAttribute(EVAL_VALUE, value);
break;
case RegExp:
case RLike: {
String pattern = castToString(right.getAttributes().get(EVAL_VALUE));
String pattern = castToString(rightValue);
String input = castToString(left.getAttributes().get(EVAL_VALUE));
boolean matchResult = Pattern.matches(pattern, input);
x.putAttribute(EVAL_VALUE, matchResult);
@@ -860,26 +886,31 @@ public class SQLEvalVisitorUtils {
break;
case NotRegExp:
case NotRLike: {
String pattern = castToString(right.getAttributes().get(EVAL_VALUE));
String pattern = castToString(rightValue);
String input = castToString(left.getAttributes().get(EVAL_VALUE));
boolean matchResult = !Pattern.matches(pattern, input);
x.putAttribute(EVAL_VALUE, matchResult);
}
break;
case Like: {
String pattern = castToString(right.getAttributes().get(EVAL_VALUE));
String pattern = castToString(rightValue);
String input = castToString(left.getAttributes().get(EVAL_VALUE));
boolean matchResult = like(input, pattern);
x.putAttribute(EVAL_VALUE, matchResult);
}
break;
case NotLike: {
String pattern = castToString(right.getAttributes().get(EVAL_VALUE));
String pattern = castToString(rightValue);
String input = castToString(left.getAttributes().get(EVAL_VALUE));
boolean matchResult = !like(input, pattern);
x.putAttribute(EVAL_VALUE, matchResult);
}
break;
case Concat: {
String result = leftValue.toString() + rightValue.toString();
x.putAttribute(EVAL_VALUE, result);
break;
}
default:
break;
}
@@ -58,7 +58,6 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.stat.TableStat;
@@ -51,6 +51,7 @@ public class WallConfig implements WallConfigMBean {
private boolean commentAllow = false;
private boolean strictSyntaxCheck = true;
private boolean constArithmeticAllow = false;
private boolean describeAllow = false;
@@ -366,6 +367,14 @@ public class WallConfig implements WallConfigMBean {
this.strictSyntaxCheck = strictSyntaxCheck;
}
public boolean isConstArithmeticAllow() {
return constArithmeticAllow;
}
public void setConstArithmeticAllow(boolean constArithmeticAllow) {
this.constArithmeticAllow = constArithmeticAllow;
}
public Set<String> getDenyFunctions() {
return denyFunctions;
}
@@ -20,11 +20,16 @@ public class WallContext {
private final static ThreadLocal<WallContext> contextLocal = new ThreadLocal<WallContext>();
private WallSqlStat sqlState;
private final String dbType;
public static WallContext createIfNotExists() {
public WallContext(String dbType){
this.dbType = dbType;
}
public static WallContext createIfNotExists(String dbType) {
WallContext context = contextLocal.get();
if (context == null) {
context = new WallContext();
context = new WallContext(dbType);
contextLocal.set(context);
}
return context;
@@ -46,4 +51,8 @@ public class WallContext {
this.sqlState = sqlState;
}
public String getDbType() {
return dbType;
}
}
@@ -159,7 +159,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public void statement_addBatch(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
chain.statement_addBatch(statement, sql);
@@ -171,7 +172,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection, String sql)
throws SQLException {
WallContext.createIfNotExists();
String dbType = connection.getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.connection_prepareStatement(connection, sql);
@@ -183,7 +185,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection,
String sql, int autoGeneratedKeys) throws SQLException {
WallContext.createIfNotExists();
String dbType = connection.getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.connection_prepareStatement(connection, sql, autoGeneratedKeys);
@@ -196,7 +199,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection,
String sql, int resultSetType, int resultSetConcurrency)
throws SQLException {
WallContext.createIfNotExists();
String dbType = connection.getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.connection_prepareStatement(connection, sql, resultSetType, resultSetConcurrency);
@@ -209,7 +213,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection,
String sql, int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
WallContext.createIfNotExists();
String dbType = connection.getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.connection_prepareStatement(connection, sql, resultSetType, resultSetConcurrency,
@@ -222,7 +227,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection,
String sql, int[] columnIndexes) throws SQLException {
WallContext.createIfNotExists();
String dbType = connection.getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.connection_prepareStatement(connection, sql, columnIndexes);
@@ -234,7 +240,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection,
String sql, String[] columnNames) throws SQLException {
WallContext.createIfNotExists();
String dbType = connection.getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.connection_prepareStatement(connection, sql, columnNames);
@@ -246,7 +253,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public CallableStatementProxy connection_prepareCall(FilterChain chain, ConnectionProxy connection, String sql)
throws SQLException {
WallContext.createIfNotExists();
String dbType = connection.getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.connection_prepareCall(connection, sql);
@@ -259,7 +267,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
public CallableStatementProxy connection_prepareCall(FilterChain chain, ConnectionProxy connection, String sql,
int resultSetType, int resultSetConcurrency)
throws SQLException {
WallContext.createIfNotExists();
String dbType = connection.getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.connection_prepareCall(connection, sql, resultSetType, resultSetConcurrency);
@@ -272,7 +281,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
public CallableStatementProxy connection_prepareCall(FilterChain chain, ConnectionProxy connection, String sql,
int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
WallContext.createIfNotExists();
String dbType = connection.getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.connection_prepareCall(connection, sql, resultSetType, resultSetConcurrency,
@@ -286,7 +296,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.statement_execute(statement, sql);
@@ -298,7 +309,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, int autoGeneratedKeys)
throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.statement_execute(statement, sql, autoGeneratedKeys);
@@ -310,7 +322,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, int columnIndexes[])
throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.statement_execute(statement, sql, columnIndexes);
@@ -322,7 +335,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, String columnNames[])
throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.statement_execute(statement, sql, columnNames);
@@ -334,7 +348,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public ResultSetProxy statement_executeQuery(FilterChain chain, StatementProxy statement, String sql)
throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.statement_executeQuery(statement, sql);
@@ -345,7 +360,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.statement_executeUpdate(statement, sql);
@@ -357,7 +373,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int autoGeneratedKeys)
throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.statement_executeUpdate(statement, sql, autoGeneratedKeys);
@@ -369,7 +386,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int columnIndexes[])
throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.statement_executeUpdate(statement, sql, columnIndexes);
@@ -381,7 +399,8 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
@Override
public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, String columnNames[])
throws SQLException {
WallContext.createIfNotExists();
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
WallContext.createIfNotExists(dbType);
try {
sql = check(sql);
return chain.statement_executeUpdate(statement, sql, columnNames);
@@ -465,15 +484,15 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
public long getViolationCount() {
return this.violationCount.get();
}
public void resetViolationCount() {
this.violationCount.set(0);
}
public void clearWhiteList() {
this.provider.clearCache();
}
public boolean checkValid(String sql) {
return provider.checkValid(sql);
}
@@ -29,6 +29,7 @@ import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.LRUCache;
import com.alibaba.druid.wall.spi.WallVisitorUtils;
import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;
@@ -54,9 +55,16 @@ public abstract class WallProvider {
public final WallDenyStat commentDeniedStat = new WallDenyStat();
protected String dbType = null;
public WallProvider(WallConfig config){
this.config = config;
}
public WallProvider(WallConfig config, String dbType){
this.config = config;
this.dbType = dbType;
}
public WallConfig getConfig() {
return config;
@@ -128,6 +136,7 @@ public abstract class WallProvider {
public abstract ExportParameterVisitor createExportParameterVisitor();
public boolean checkValid(String sql) {
WallContext.createIfNotExists(dbType);
WallCheckResult result = check(sql);
return result.getViolations().isEmpty();
}
@@ -262,7 +271,7 @@ public abstract class WallProvider {
return result;
} catch (ParserException e) {
if (config.isStrictSyntaxCheck()) {
result.getViolations().add(new SyntaxErrorViolation(e, sql));
result.getViolations().add(new SyntaxErrorViolation(e, sql));
}
return result;
} catch (Exception e) {
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlExportParameterVisitor;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallVisitor;
@@ -32,7 +33,7 @@ public class MySqlWallProvider extends WallProvider {
}
public MySqlWallProvider(WallConfig config){
super(config);
super(config, JdbcConstants.MYSQL);
}
@Override
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleExportParameterVisitor;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallVisitor;
@@ -32,7 +33,7 @@ public class OracleWallProvider extends WallProvider {
}
public OracleWallProvider(WallConfig config){
super(config);
super(config, JdbcConstants.ORACLE);
}
@Override
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.MSSQLServerExportParameterVisitor;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallVisitor;
@@ -42,7 +43,7 @@ public class SQLServerWallProvider extends WallProvider {
}
public SQLServerWallProvider(WallConfig config){
super(config);
super(config, JdbcConstants.SQL_SERVER);
}
@Override
@@ -19,9 +19,9 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
@@ -40,7 +40,6 @@ import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLNotExpr;
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
@@ -59,17 +58,19 @@ import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.ServletPathMatcher;
import com.alibaba.druid.wall.WallContext;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallVisitor;
import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;
public class WallVisitorUtils {
private final static Log LOG = LogFactory.getLog(WallVisitorUtils.class);
private final static Log LOG = LogFactory.getLog(WallVisitorUtils.class);
public static void check(WallVisitor visitor, SQLInListExpr x) {
@@ -121,17 +122,13 @@ public class WallVisitorUtils {
return;
}
if (!visitor.getConfig().isSelectWhereAlwayTrueCheck()) {
return;
}
SQLExpr where = x.getWhere();
if (where != null) {
x.getWhere().setParent(x);
checkCondition(visitor, x.getWhere());
if (Boolean.TRUE == getConditionValue(visitor, where)) {
if (Boolean.TRUE == getConditionValue(visitor, where, visitor.getConfig().isSelectWhereAlwayTrueCheck())) {
boolean isSimpleConstExpr = false;
if (where instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) where;
@@ -158,11 +155,7 @@ public class WallVisitorUtils {
return;
}
if (!visitor.getConfig().isSelectHavingAlwayTrueCheck()) {
return;
}
if (Boolean.TRUE == getConditionValue(visitor, x)) {
if (Boolean.TRUE == getConditionValue(visitor, x, visitor.getConfig().isSelectHavingAlwayTrueCheck())) {
addViolation(visitor, x);
}
}
@@ -175,11 +168,9 @@ public class WallVisitorUtils {
return;
}
if (!visitor.getConfig().isDeleteWhereAlwayTrueCheck()) {
return;
}
if (x.getWhere() == null || Boolean.TRUE == getConditionValue(visitor, x.getWhere())) {
if (x.getWhere() == null
|| Boolean.TRUE == getConditionValue(visitor, x.getWhere(),
visitor.getConfig().isDeleteWhereAlwayTrueCheck())) {
addViolation(visitor, x);
return;
}
@@ -368,11 +359,9 @@ public class WallVisitorUtils {
return;
}
if (!visitor.getConfig().isUpdateWhereAlayTrueCheck()) {
return;
}
if (x.getWhere() == null || Boolean.TRUE == getConditionValue(visitor, x.getWhere())) {
if (x.getWhere() == null
|| Boolean.TRUE == getConditionValue(visitor, x.getWhere(),
visitor.getConfig().isUpdateWhereAlayTrueCheck())) {
addViolation(visitor, x);
return;
}
@@ -382,7 +371,6 @@ public class WallVisitorUtils {
checkConditionForMultiTenant(visitor, x.getWhere(), x);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Object getValue(SQLBinaryOpExpr x) {
x.getLeft().setParent(x);
x.getRight().setParent(x);
@@ -434,7 +422,7 @@ public class WallVisitorUtils {
if (Boolean.TRUE == result) {
final WallConditionContext wallContext = WallVisitorUtils.getWallConditionContext();
if (wallContext != null) {
wallContext.setPartAllowTrue(true);
wallContext.setPartAlwayTrue(true);
}
return true;
}
@@ -458,11 +446,11 @@ public class WallVisitorUtils {
if (Boolean.FALSE == leftResult || Boolean.FALSE == rightResult) {
return false;
}
if (leftResult == Boolean.TRUE || rightResult == Boolean.TRUE) {
final WallConditionContext current = wallConditionContextLocal.get();
if (current != null) {
current.setPartAllowTrue(true);
current.setPartAlwayTrue(true);
}
}
@@ -471,162 +459,59 @@ public class WallVisitorUtils {
}
}
if (x.getOperator() == SQLBinaryOperator.Like) {
if (x.getRight() instanceof SQLCharExpr) {
String text = ((SQLCharExpr) x.getRight()).getText();
if (text.length() >= 0) {
for (char ch : text.toCharArray()) {
if (ch != '%') {
return null;
}
}
return true;
}
}
String dbType = null;
WallContext wallContext = WallContext.current();
if (wallContext != null) {
dbType = wallContext.getDbType();
}
if (leftResult == null || rightResult == null) {
return null;
}
if (x.getOperator() == SQLBinaryOperator.Equality) {
if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) {
return true;
}
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;
}
}
if (x.getOperator() == SQLBinaryOperator.Concat) {
return leftResult.toString() + rightResult.toString();
}
if (x.getOperator() == SQLBinaryOperator.Add) {
if (leftResult == null || rightResult == null) {
return null;
}
if (leftResult instanceof String || rightResult instanceof String) {
return leftResult.toString() + rightResult.toString();
}
if (leftResult instanceof Number || rightResult instanceof Number) {
return add((Number) leftResult, (Number) rightResult);
}
}
return null;
}
private static Number add(Number a, Number b) {
if (a instanceof BigDecimal) {
return ((BigDecimal) a).add(new BigDecimal(b.toString()));
}
return a.longValue() + b.longValue();
return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false);
}
public static class WallConditionContext {
private boolean partAllowTrue;
private boolean constArithmetic = false;
public boolean isPartAllowTrue() {
return partAllowTrue;
}
public void setPartAllowTrue(boolean partAllowTrue) {
public void setPartAlwayTrue(boolean partAllowTrue) {
this.partAllowTrue = partAllowTrue;
}
public boolean isConstArithmetic() {
return constArithmetic;
}
public void setConstArithmetic(boolean constArithmetic) {
this.constArithmetic = constArithmetic;
}
}
private static ThreadLocal<WallConditionContext> wallConditionContextLocal = new ThreadLocal<WallConditionContext>();
public static WallConditionContext getWallConditionContext() {
return wallConditionContextLocal.get();
}
public static Object getConditionValue(WallVisitor visitor, SQLExpr x) {
public static Object getConditionValue(WallVisitor visitor, SQLExpr x, boolean alwayTrueCheck) {
final WallConditionContext old = wallConditionContextLocal.get();
try {
wallConditionContextLocal.set(new WallConditionContext());
final Object value = getValue(x);
final WallConditionContext current = wallConditionContextLocal.get();
if (current.isPartAllowTrue() && visitor.getConfig().isUpdateWhereAlayTrueCheck()) {
if (current.isPartAllowTrue() && alwayTrueCheck) {
addViolation(visitor, x);
}
if (current.isConstArithmetic() && !visitor.getConfig().isConstArithmeticAllow()) {
addViolation(visitor, x);
}
return value;
} finally {
wallConditionContextLocal.set(old);
@@ -807,7 +692,7 @@ public class WallVisitorUtils {
if (x instanceof SQLPropertyExpr) {
return checkSchema(visitor, ((SQLPropertyExpr) x).getOwner());
}
return true;
}
@@ -828,7 +713,7 @@ public class WallVisitorUtils {
return false;
}
}
return true;
}