diff --git a/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java index e42e51012a..50702ad849 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/filter/wall/spi/WallVisitorUtils.java @@ -8,6 +8,8 @@ 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.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.SQLNumericLiteralExpr; @@ -22,13 +24,13 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr; public class WallVisitorUtils { public static void check(WallVisitor visitor, SQLBinaryOpExpr x) { - if (Boolean.TRUE == getObject(x)) { + if (Boolean.TRUE == getValue(x)) { visitor.getViolations().add(new IllegalConditionViolation(SQLUtils.toSQLString(x))); } } @SuppressWarnings({ "unchecked", "rawtypes" }) - public static Object getObject(SQLBinaryOpExpr x) { + public static Object getValue(SQLBinaryOpExpr x) { x.getLeft().setParent(x); x.getRight().setParent(x); Object leftResult = getValue(x.getLeft()); @@ -106,7 +108,7 @@ public class WallVisitorUtils { if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { return false; } - + if (leftResult == null || rightResult == null) { return null; } @@ -149,10 +151,10 @@ public class WallVisitorUtils { return null; } - + public static Object getValue(SQLExpr x) { if (x instanceof SQLBinaryOpExpr) { - return getObject((SQLBinaryOpExpr) x); + return getValue((SQLBinaryOpExpr) x); } if (x instanceof MySqlBooleanExpr) { @@ -162,6 +164,14 @@ public class WallVisitorUtils { if (x instanceof SQLNumericLiteralExpr) { return ((SQLNumericLiteralExpr) x).getNumber(); } + + if (x instanceof SQLCharExpr) { + return ((SQLCharExpr) x).getText(); + } + + if (x instanceof SQLNCharExpr) { + return ((SQLNCharExpr) x).getText(); + } if (x instanceof SQLNotExpr) { Object result = getValue(((SQLNotExpr) x).getExpr()); @@ -169,13 +179,33 @@ public class WallVisitorUtils { return !((Boolean) result).booleanValue(); } } - + if (x instanceof SQLQueryExpr) { if (isSimpleCountTableSource(((SQLQueryExpr) x).getSubQuery())) { return Integer.valueOf(1); } } + if (x instanceof SQLMethodInvokeExpr) { + return getValue((SQLMethodInvokeExpr) x); + } + + return null; + } + + public static Object getValue(SQLMethodInvokeExpr x) { + String methodName = x.getMethodName(); + if ("len".equalsIgnoreCase(methodName) || "length".equalsIgnoreCase(methodName)) { + Object firstValue = null; + if (x.getParameters().size() > 0) { + firstValue = (getValue(x.getParameters().get(0))); + } + + if (firstValue instanceof String) { + return ((String) firstValue).length(); + } + } + return null; } @@ -188,14 +218,25 @@ public class WallVisitorUtils { 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 allawTrueWhere = false; + + if (queryBlock.getWhere() == null) { + allawTrueWhere = true; + } else { + Object whereValue = getValue(queryBlock.getWhere()); + if (whereValue == Boolean.TRUE) { + allawTrueWhere = true; + } else if (whereValue == Boolean.FALSE) { + return false; + } + } boolean simpleCount = false; if (queryBlock.getSelectList().size() == 1) { SQLExpr selectItemExpr = queryBlock.getSelectList().get(0).getExpr(); diff --git a/src/main/resources/META-INF/druid-filter.properties b/src/main/resources/META-INF/druid-filter.properties index a997f063c4..9feea335b5 100644 --- a/src/main/resources/META-INF/druid-filter.properties +++ b/src/main/resources/META-INF/druid-filter.properties @@ -6,4 +6,5 @@ druid.filters.log4j=com.alibaba.druid.filter.logging.Log4jFilter druid.filters.slf4j=com.alibaba.druid.filter.logging.Slf4jLogFilter druid.filters.commonlogging=com.alibaba.druid.filter.logging.CommonsLogFilter druid.filters.commonLogging=com.alibaba.druid.filter.logging.CommonsLogFilter -druid.filters.trace=com.alibaba.druid.filter.trace.TraceFilter \ No newline at end of file +druid.filters.trace=com.alibaba.druid.filter.trace.TraceFilter +druid.filters.wall=com.alibaba.druid.filter.wall.WallFilter \ No newline at end of file diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallVisitorUtilsTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallVisitorUtilsTest.java index bc604aca7c..aac3070e54 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallVisitorUtilsTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallVisitorUtilsTest.java @@ -27,6 +27,9 @@ public class WallVisitorUtilsTest extends TestCase { 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("len('44') > 0"))); + Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("len('44') >= 2"))); + Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("(select count(*) from t) > 0"))); Assert.assertEquals(Boolean.TRUE, WallVisitorUtils.getValue(SQLUtils.toSQLExpr("(select count(*) from t) >= 0"))); }