From 700862624bde644ae7b1b70a549a53e4deced23c Mon Sep 17 00:00:00 2001 From: wenshao Date: Tue, 28 May 2013 10:40:34 +0800 Subject: [PATCH] improve wallfilter --- .../sql/ast/statement/SQLInsertStatement.java | 3 ++ .../parser/SQLServerStatementParser.java | 2 +- .../druid/sql/parser/SQLExprParser.java | 11 ++++- .../druid/wall/spi/WallVisitorUtils.java | 35 +++++++++++--- .../bvt/filter/wall/SQLServerWallTest_3.java | 46 +++++++++++++++++++ .../bvt/filter/wall/SQLServerWallTest_4.java | 46 +++++++++++++++++++ .../bvt/filter/wall/SQLServerWallTest_5.java | 46 +++++++++++++++++++ .../bvt/filter/wall/SQLServerWallTest_6.java | 46 +++++++++++++++++++ .../MySqlValidConnectionCheckerTest.java | 8 ++++ 9 files changed, 233 insertions(+), 10 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_3.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_4.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_5.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_6.java create mode 100644 src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlValidConnectionCheckerTest.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java index 005737309e..b22782d7cc 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java @@ -54,6 +54,9 @@ public class SQLInsertStatement extends SQLInsertInto implements SQLStatement { public ValuesClause(List values){ this.values = values; + for (int i = 0; i < values.size(); ++i) { + values.get(i).setParent(this); + } } public List getValues() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index ee10fc9553..bec3ebfb4a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -100,7 +100,7 @@ public class SQLServerStatementParser extends SQLStatementParser { for (;;) { accept(Token.LPAREN); SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(); - this.exprParser.exprList(values.getValues()); + this.exprParser.exprList(values.getValues(), values); insertStatement.getValuesList().add(values); accept(Token.RPAREN); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index ff1b010608..46790d1c67 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -25,6 +25,7 @@ import com.alibaba.druid.sql.ast.SQLDataType; import com.alibaba.druid.sql.ast.SQLDataTypeImpl; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLOrderBy; import com.alibaba.druid.sql.ast.SQLOrderingSpecification; import com.alibaba.druid.sql.ast.SQLOver; @@ -536,7 +537,7 @@ public class SQLExprParser extends SQLParser { } if (lexer.token() != Token.RPAREN) { - exprList(methodInvokeExpr.getParameters()); + exprList(methodInvokeExpr.getParameters(), methodInvokeExpr); } accept(Token.RPAREN); @@ -611,8 +612,12 @@ public class SQLExprParser extends SQLParser { exprCol.add(name()); } } - + public final void exprList(Collection exprCol) { + exprList(exprCol, null); + } + + public final void exprList(Collection exprCol, SQLObject parent) { if (lexer.token() == Token.RPAREN || lexer.token() == Token.RBRACKET) { return; } @@ -622,11 +627,13 @@ public class SQLExprParser extends SQLParser { } SQLExpr expr = expr(); + expr.setParent(parent); exprCol.add(expr); while (lexer.token() == Token.COMMA) { lexer.nextToken(); expr = expr(); + expr.setParent(parent); exprCol.add(expr); } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java index 8345a92223..9e5de6c5b9 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -204,7 +204,7 @@ public class WallVisitorUtils { if (Boolean.TRUE == getConditionValue(visitor, where, visitor.getConfig().isSelectWhereAlwayTrueCheck())) { boolean isSimpleConstExpr = false; SQLExpr first = getFirst(where); - + if (first == where) { isSimpleConstExpr = true; } else if (first instanceof SQLBinaryOpExpr) { @@ -245,9 +245,9 @@ public class WallVisitorUtils { } } } - + if (!isSimpleConstExpr) { - addViolation(visitor, ErrorCode.ALWAY_TRUE, "having alway true condition not allow", x); + addViolation(visitor, ErrorCode.ALWAY_TRUE, "having alway true condition not allow", x); } } } @@ -621,15 +621,16 @@ public class WallVisitorUtils { return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false); } - + public static SQLExpr getFirst(SQLExpr x) { if (x instanceof SQLBinaryOpExpr) { SQLBinaryOpExpr binary = (SQLBinaryOpExpr) x; - if (binary.getOperator() == SQLBinaryOperator.BooleanAnd || binary.getOperator() == SQLBinaryOperator.BooleanOr) { + if (binary.getOperator() == SQLBinaryOperator.BooleanAnd + || binary.getOperator() == SQLBinaryOperator.BooleanOr) { return getFirst(((SQLBinaryOpExpr) x).getLeft()); } } - + return x; } @@ -673,6 +674,24 @@ public class WallVisitorUtils { return false; } } + + if (parent instanceof SQLDeleteStatement) { + SQLDeleteStatement delete = (SQLDeleteStatement) parent; + if (delete.getWhere() == x) { + return true; + } else { + return false; + } + } + + if (parent instanceof SQLUpdateStatement) { + SQLUpdateStatement update = (SQLUpdateStatement) parent; + if (update.getWhere() == x) { + return true; + } else { + return false; + } + } if (parent instanceof SQLSelectGroupByClause) { SQLSelectGroupByClause groupBy = (SQLSelectGroupByClause) parent; @@ -952,7 +971,9 @@ public class WallVisitorUtils { } } - addViolation(visitor, ErrorCode.FUNCTION_DENY, "deny function : " + methodName, x); + if (isWhereOrHaving(x)) { + addViolation(visitor, ErrorCode.FUNCTION_DENY, "deny function : " + methodName, x); + } } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_3.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_3.java new file mode 100644 index 0000000000..5a9274f274 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_3.java @@ -0,0 +1,46 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class SQLServerWallTest_3 extends TestCase { + + public void test_true() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + + provider.getConfig().setSelectHavingAlwayTrueCheck(true); + + Assert.assertFalse(provider.checkValid(// + "select * from t where LEN(HOST_NAME()) > 0")); + + Assert.assertEquals(1, provider.getTableStats().size()); + Assert.assertTrue(provider.getTableStats().containsKey("t")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_4.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_4.java new file mode 100644 index 0000000000..d8a31b7f98 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_4.java @@ -0,0 +1,46 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class SQLServerWallTest_4 extends TestCase { + + public void test_true() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + + provider.getConfig().setSelectHavingAlwayTrueCheck(true); + + Assert.assertTrue(provider.checkValid(// + "insert into t (fid, name) values (1, HOST_NAME())")); + + Assert.assertEquals(1, provider.getTableStats().size()); + Assert.assertTrue(provider.getTableStats().containsKey("t")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_5.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_5.java new file mode 100644 index 0000000000..55c8a2af05 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_5.java @@ -0,0 +1,46 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class SQLServerWallTest_5 extends TestCase { + + public void test_true() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + + provider.getConfig().setSelectHavingAlwayTrueCheck(true); + + Assert.assertFalse(provider.checkValid(// + "delete t where LEN(HOST_NAME()) > 0")); + + Assert.assertEquals(1, provider.getTableStats().size()); + Assert.assertTrue(provider.getTableStats().containsKey("t")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_6.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_6.java new file mode 100644 index 0000000000..75968fbdd9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/SQLServerWallTest_6.java @@ -0,0 +1,46 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.SQLServerWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class SQLServerWallTest_6 extends TestCase { + + public void test_true() throws Exception { + WallProvider provider = new SQLServerWallProvider(); + + provider.getConfig().setSelectHavingAlwayTrueCheck(true); + + Assert.assertFalse(provider.checkValid(// + "update t set fid = 1 where LEN(HOST_NAME()) > 0")); + + Assert.assertEquals(1, provider.getTableStats().size()); + Assert.assertTrue(provider.getTableStats().containsKey("t")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlValidConnectionCheckerTest.java b/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlValidConnectionCheckerTest.java new file mode 100644 index 0000000000..8eafedbc71 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/vendor/MySqlValidConnectionCheckerTest.java @@ -0,0 +1,8 @@ +package com.alibaba.druid.bvt.pool.vendor; + +import junit.framework.TestCase; + + +public class MySqlValidConnectionCheckerTest extends TestCase { + +}