From 78c7456ef0e4dda1ef0b971c26ab05f142dee9de Mon Sep 17 00:00:00 2001 From: wenshao Date: Tue, 2 Apr 2013 19:52:40 +0800 Subject: [PATCH] improve wall filter --- .../sql/ast/statement/SQLSelectItem.java | 8 +- .../dialect/mysql/parser/MySqlExprParser.java | 3 + .../mysql/parser/MySqlStatementParser.java | 26 +-- .../mysql/visitor/MySqlSchemaStatVisitor.java | 150 +++++++++--------- .../druid/sql/parser/EOFParserException.java | 24 +++ .../druid/sql/parser/SQLExprParser.java | 11 +- .../druid/sql/parser/SQLStatementParser.java | 2 +- .../druid/stat/DruidStatManagerFacade.java | 4 +- .../alibaba/druid/stat/DruidStatService.java | 1 - .../com/alibaba/druid/wall/WallConfig.java | 20 ++- .../alibaba/druid/wall/WallFunctionStat.java | 6 +- .../com/alibaba/druid/wall/WallProvider.java | 55 ++++++- .../com/alibaba/druid/wall/WallSqlStat.java | 16 +- .../druid/wall/spi/MySqlWallVisitor.java | 88 +++++++--- .../druid/wall/spi/OracleWallVisitor.java | 6 + .../alibaba/druid/wall/spi/PGWallVisitor.java | 6 + .../druid/wall/spi/SQLServerWallVisitor.java | 6 + .../druid/wall/mysql/permit-variant.txt | 21 +++ .../bvt/filter/wall/MySqlWallTest34.java | 37 +++++ .../bvt/filter/wall/MySqlWallTest_var.java | 52 ++++++ .../wall/MySqlWallTest_var_autoincrement.java | 5 +- .../druid/bvt/filter/wall/WallDropTest.java | 21 ++- .../WallStatTest_blackList_syntaxError.java | 53 +++++++ .../WallStatTest_whiteList_syntaxError.java | 54 +++++++ .../bvt/filter/wall/WallTruncateTest.java | 18 ++- .../druid/bvt/sql/mysql/MySqlError_test.java | 42 +++++ .../bvt/sql/mysql/MySqlError_test_1.java | 40 +++++ .../bvt/sql/mysql/MySqlError_test_2.java | 40 +++++ .../bvt/sql/mysql/MySqlError_test_3.java | 44 +++++ .../bvt/sql/mysql/MySqlSelectTest_9.java | 61 +++++++ .../bvt/sql/mysql/MySqlShowTest_table.java | 51 ++++++ 31 files changed, 824 insertions(+), 147 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/parser/EOFParserException.java create mode 100644 src/main/resources/META-INF/druid/wall/mysql/permit-variant.txt create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest34.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_blackList_syntaxError.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_whiteList_syntaxError.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_1.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_2.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_3.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_9.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlShowTest_table.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectItem.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectItem.java index 68b60494ec..5d78228a68 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectItem.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLSelectItem.java @@ -35,9 +35,12 @@ public class SQLSelectItem extends SQLObjectImpl { } public SQLSelectItem(SQLExpr expr, String alias){ - this.expr = expr; this.alias = alias; + + if (expr != null) { + expr.setParent(this); + } } public SQLExpr getExpr() { @@ -46,6 +49,9 @@ public class SQLSelectItem extends SQLObjectImpl { public void setExpr(SQLExpr expr) { this.expr = expr; + if (expr != null) { + expr.setParent(this); + } } public String getAlias() { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java index ae37677ef0..f04194e9c9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java @@ -171,6 +171,9 @@ public class MySqlExprParser extends SQLExprParser { SQLUnaryExpr binaryExpr = new SQLUnaryExpr(SQLUnaryOperator.BINARY, expr()); return primaryRest(binaryExpr); } + case GROUP: + lexer.nextToken(); + return primaryRest(new SQLIdentifierExpr(lexer.stringVal())); default: return super.primary(); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 02153e0b14..29fddfbff3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -236,7 +236,7 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.DELETE) { lexer.nextToken(); - + if (lexer.token() == Token.COMMENT) { lexer.nextToken(); } @@ -639,20 +639,23 @@ public class MySqlStatementParser extends SQLStatementParser { public SQLStatement parseShow() { acceptIdentifier("SHOW"); + boolean full = false; if (lexer.token() == Token.FULL) { lexer.nextToken(); + } - if (identifierEquals("PROCESSLIST")) { - lexer.nextToken(); - MySqlShowProcessListStatement stmt = new MySqlShowProcessListStatement(); - stmt.setFull(true); - return stmt; - } + if (identifierEquals("PROCESSLIST")) { + lexer.nextToken(); + MySqlShowProcessListStatement stmt = new MySqlShowProcessListStatement(); + stmt.setFull(full); + return stmt; + } - acceptIdentifier("COLUMNS"); + if (identifierEquals("COLUMNS")) { + lexer.nextToken(); MySqlShowColumnsStatement stmt = parseShowColumns(); - stmt.setFull(true); + stmt.setFull(full); return stmt; } @@ -669,6 +672,7 @@ public class MySqlStatementParser extends SQLStatementParser { lexer.nextToken(); MySqlShowTablesStatement stmt = parseShowTabless(); + stmt.setFull(full); return stmt; } @@ -2245,9 +2249,9 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.PRIMARY) { SQLPrimaryKey primaryKey = ((MySqlExprParser) this.exprParser).parsePrimaryKey(); - + primaryKey.setName(constraintName); - + SQLAlterTableAddPrimaryKey item = new SQLAlterTableAddPrimaryKey(); item.setPrimaryKey(primaryKey); stmt.getItems().add(item); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index ea9aa4727a..1d7a71db66 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -146,7 +146,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS return true; } - + @Override public String getDbType() { return JdbcUtils.MYSQL; @@ -432,7 +432,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public boolean visit(MySqlShowTablesStatement x) { - return true; + return false; } @Override @@ -442,7 +442,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public boolean visit(MySqlShowDatabasesStatement x) { - return true; + return false; } @Override @@ -666,15 +666,15 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS public void endVisit(MySqlShowCollationStatement x) { } - + @Override public boolean visit(MySqlShowBinLogEventsStatement x) { return false; } - + @Override public void endVisit(MySqlShowBinLogEventsStatement x) { - + } @Override @@ -684,27 +684,27 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowCharacterSetStatement x) { - + } - + @Override public boolean visit(MySqlShowContributorsStatement x) { return false; } - + @Override public void endVisit(MySqlShowContributorsStatement x) { - + } - + @Override public boolean visit(MySqlShowCreateDatabaseStatement x) { return false; } - + @Override public void endVisit(MySqlShowCreateDatabaseStatement x) { - + } @Override @@ -714,7 +714,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowCreateEventStatement x) { - + } @Override @@ -724,7 +724,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowCreateFunctionStatement x) { - + } @Override @@ -734,7 +734,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowCreateProcedureStatement x) { - + } @Override @@ -744,7 +744,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowCreateTableStatement x) { - + } @Override @@ -754,7 +754,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowCreateTriggerStatement x) { - + } @Override @@ -764,7 +764,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowCreateViewStatement x) { - + } @Override @@ -774,17 +774,17 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowEngineStatement x) { - + } - + @Override public boolean visit(MySqlShowEnginesStatement x) { return false; } - + @Override public void endVisit(MySqlShowEnginesStatement x) { - + } @Override @@ -794,7 +794,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowErrorsStatement x) { - + } @Override @@ -804,7 +804,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowEventsStatement x) { - + } @Override @@ -814,7 +814,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowFunctionCodeStatement x) { - + } @Override @@ -824,7 +824,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowFunctionStatusStatement x) { - + } @Override @@ -834,7 +834,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowGrantsStatement x) { - + } @Override @@ -844,7 +844,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlUserName x) { - + } @Override @@ -854,7 +854,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowIndexesStatement x) { - + } @Override @@ -864,7 +864,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowKeysStatement x) { - + } @Override @@ -874,7 +874,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowMasterStatusStatement x) { - + } @Override @@ -884,7 +884,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowOpenTablesStatement x) { - + } @Override @@ -894,7 +894,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowPluginsStatement x) { - + } @Override @@ -904,7 +904,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowPrivilegesStatement x) { - + } @Override @@ -914,7 +914,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowProcedureCodeStatement x) { - + } @Override @@ -924,7 +924,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowProcedureStatusStatement x) { - + } @Override @@ -934,7 +934,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowProcessListStatement x) { - + } @Override @@ -944,7 +944,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowProfileStatement x) { - + } @Override @@ -954,7 +954,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowProfilesStatement x) { - + } @Override @@ -964,7 +964,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowRelayLogEventsStatement x) { - + } @Override @@ -974,7 +974,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowSlaveHostsStatement x) { - + } @Override @@ -984,7 +984,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowSlaveStatusStatement x) { - + } @Override @@ -994,7 +994,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowTableStatusStatement x) { - + } @Override @@ -1004,7 +1004,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowTriggersStatement x) { - + } @Override @@ -1014,7 +1014,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlShowVariantsStatement x) { - + } @Override @@ -1035,7 +1035,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableStatement x) { - + } @Override @@ -1045,17 +1045,17 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableAddColumn x) { - + } - + @Override public boolean visit(MySqlCreateIndexStatement x) { return false; } - + @Override public void endVisit(MySqlCreateIndexStatement x) { - + } @Override @@ -1065,7 +1065,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlRenameTableStatement.Item x) { - + } @Override @@ -1075,7 +1075,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlRenameTableStatement x) { - + } @Override @@ -1086,7 +1086,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlDropViewStatement x) { - + } @Override @@ -1096,7 +1096,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlUnionQuery x) { - + } @Override @@ -1106,7 +1106,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlUseIndexHint x) { - + } @Override @@ -1116,7 +1116,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlIgnoreIndexHint x) { - + } @Override @@ -1126,7 +1126,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlLockTableStatement x) { - + } @Override @@ -1136,7 +1136,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlUnlockTablesStatement x) { - + } @Override @@ -1146,7 +1146,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlForceIndexHint x) { - + } @Override @@ -1161,9 +1161,9 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableChangeColumn x) { - + } - + @Override public boolean visit(MySqlAlterTableModifyColumn x) { SQLAlterTableStatement stmt = (SQLAlterTableStatement) x.getParent(); @@ -1176,7 +1176,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableModifyColumn x) { - + } @Override @@ -1186,7 +1186,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableCharacter x) { - + } @Override @@ -1196,7 +1196,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableAddIndex x) { - + } @Override @@ -1206,7 +1206,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableOption x) { - + } @Override @@ -1216,7 +1216,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlCreateTableStatement x) { - + } @Override @@ -1226,7 +1226,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlHelpStatement x) { - + } @Override @@ -1236,7 +1236,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlCharExpr x) { - + } @Override @@ -1246,7 +1246,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableAddUnique x) { - + } @Override @@ -1256,7 +1256,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlUnique x) { - + } @Override @@ -1266,7 +1266,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlForeignKey x) { - + } @Override @@ -1276,7 +1276,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableDiscardTablespace x) { - + } @Override @@ -1286,7 +1286,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS @Override public void endVisit(MySqlAlterTableImportTablespace x) { - + } - + } diff --git a/src/main/java/com/alibaba/druid/sql/parser/EOFParserException.java b/src/main/java/com/alibaba/druid/sql/parser/EOFParserException.java new file mode 100644 index 0000000000..c280d7c26f --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/parser/EOFParserException.java @@ -0,0 +1,24 @@ +/* + * 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.sql.parser; + +@SuppressWarnings("serial") +public class EOFParserException extends ParserException { + + public EOFParserException(){ + super("EOF"); + } +} 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 b397a1a84c..565e9ddd21 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -457,8 +457,10 @@ public class SQLExprParser extends SQLParser { sqlExpr = new SQLIdentifierExpr('"' + lexer.stringVal() + '"'); lexer.nextToken(); break; + case EOF: + throw new EOFParserException(); default: - throw new ParserException("ERROR. token : " + tok + " " + lexer.stringVal()); + throw new ParserException("ERROR. token : " + tok + ", pos : " + lexer.pos()); } return primaryRest(sqlExpr); @@ -814,8 +816,11 @@ public class SQLExprParser extends SQLParser { SQLExpr rightExp; if (lexer.token() == Token.EQ) { lexer.nextToken(); - rightExp = bitOr(); - + try { + rightExp = bitOr(); + } catch (EOFParserException e) { + throw new ParserException("EOF, " + expr + "=", e); + } rightExp = equalityRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index d34f71c4c7..10756dfede 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -223,7 +223,7 @@ public class SQLStatementParser extends SQLParser { continue; } - throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal() + ", pos " + lexer.pos()); + throw new ParserException("syntax error, " + lexer.token() + " " + lexer.stringVal() + ", pos " + lexer.pos()); } } diff --git a/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java b/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java index 9e59eb0d35..11dc85cd5c 100644 --- a/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java +++ b/src/main/java/com/alibaba/druid/stat/DruidStatManagerFacade.java @@ -158,12 +158,11 @@ public final class DruidStatManagerFacade { return new ArrayList>(); } + @SuppressWarnings("unchecked") public Map getWallStatMap(Integer dataSourceId) { Set dataSources = getDruidDataSourceInstances(); if (dataSourceId == null) { - List> sqlList = new ArrayList>(); - Map map = new HashMap(); for (Object datasource : dataSources) { @@ -186,6 +185,7 @@ public final class DruidStatManagerFacade { // } + @SuppressWarnings({ "rawtypes", "unchecked" }) static Map mergWallStat(Map mapA, Map mapB) { if (mapA.size() == 0) { return mapB; diff --git a/src/main/java/com/alibaba/druid/stat/DruidStatService.java b/src/main/java/com/alibaba/druid/stat/DruidStatService.java index c866280956..2ba4e17196 100644 --- a/src/main/java/com/alibaba/druid/stat/DruidStatService.java +++ b/src/main/java/com/alibaba/druid/stat/DruidStatService.java @@ -36,7 +36,6 @@ import com.alibaba.druid.support.json.JSONUtils; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; import com.alibaba.druid.support.spring.stat.SpringStatManager; -import com.alibaba.druid.util.DruidDataSourceUtils; import com.alibaba.druid.util.MapComparator; import com.alibaba.druid.util.StringUtils; diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index 012f2b4c79..de1b72d383 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -33,9 +33,9 @@ public class WallConfig implements WallConfigMBean { private boolean selectWhereAlwayTrueCheck = true; private boolean selectHavingAlwayTrueCheck = true; private boolean selectUnionCheck = true; - private boolean createTableAllow = false; - private boolean dropTableAllow = false; - private boolean alterTableAllow = false; + private boolean createTableAllow = true; + private boolean dropTableAllow = true; + private boolean alterTableAllow = true; private boolean selectAllColumnAllow = true; @@ -56,14 +56,14 @@ public class WallConfig implements WallConfigMBean { private boolean multiStatementAllow = false; - private boolean truncateAllow = false; + private boolean truncateAllow = true; private boolean commentAllow = false; private boolean strictSyntaxCheck = true; private boolean constArithmeticAllow = true; - private boolean describeAllow = false; - private boolean showAllow = false; + private boolean describeAllow = true; + private boolean showAllow = true; private boolean schemaCheck = true; private boolean tableCheck = true; @@ -84,6 +84,7 @@ public class WallConfig implements WallConfigMBean { protected final Set permitFunctions = new ConcurrentSkipListSet(); protected final Set permitTables = new ConcurrentSkipListSet(); protected final Set permitSchemas = new ConcurrentSkipListSet(); + protected final Set permitVariants = new ConcurrentSkipListSet(); protected final Set readOnlyTables = new ConcurrentSkipListSet(); @@ -220,6 +221,7 @@ public class WallConfig implements WallConfigMBean { loadResource(this.permitFunctions, dir + "/permit-function.txt"); loadResource(this.permitTables, dir + "/permit-table.txt"); loadResource(this.permitSchemas, dir + "/permit-schema.txt"); + loadResource(this.permitVariants, dir + "/permit-variant.txt"); } public boolean isNoneBaseStatementAllow() { @@ -353,7 +355,7 @@ public class WallConfig implements WallConfigMBean { public void setDeleteWhereAlwayTrueCheck(boolean deleteWhereAlwayTrueCheck) { this.deleteWhereAlwayTrueCheck = deleteWhereAlwayTrueCheck; } - + public boolean isDeleteWhereNoneCheck() { return deleteWhereNoneCheck; } @@ -536,6 +538,10 @@ public class WallConfig implements WallConfigMBean { return permitSchemas; } + public Set getPermitVariants() { + return permitVariants; + } + public boolean isMustParameterized() { return mustParameterized; } diff --git a/src/main/java/com/alibaba/druid/wall/WallFunctionStat.java b/src/main/java/com/alibaba/druid/wall/WallFunctionStat.java index 0999480bf0..4f24a8953f 100644 --- a/src/main/java/com/alibaba/druid/wall/WallFunctionStat.java +++ b/src/main/java/com/alibaba/druid/wall/WallFunctionStat.java @@ -30,9 +30,13 @@ public class WallFunctionStat { public void incrementInvokeCount() { this.invokeCount++; } - + public void addSqlFunctionStat(WallSqlFunctionStat sqlFunctionStat) { this.invokeCount += sqlFunctionStat.getInvokeCount(); } + public String toString() { + return "{\"invokeCount\":" + invokeCount + "}"; + } + } diff --git a/src/main/java/com/alibaba/druid/wall/WallProvider.java b/src/main/java/com/alibaba/druid/wall/WallProvider.java index b38bb74e41..aedbe294f9 100644 --- a/src/main/java/com/alibaba/druid/wall/WallProvider.java +++ b/src/main/java/com/alibaba/druid/wall/WallProvider.java @@ -47,7 +47,7 @@ public abstract class WallProvider { private int MAX_SQL_LENGTH = 2048; // 1k - private int whiteSqlMaxSize = 1000; // 1k + private int whiteSqlMaxSize = 10000; // 1k private LRUCache blackList; @@ -66,6 +66,7 @@ public abstract class WallProvider { protected String dbType = null; protected final AtomicLong checkCount = new AtomicLong(); + protected final AtomicLong hardCheckCount = new AtomicLong(); protected final AtomicLong whiteListHitCount = new AtomicLong(); protected final AtomicLong blackListHitCount = new AtomicLong(); protected final AtomicLong syntaxErrrorCount = new AtomicLong(); @@ -81,7 +82,13 @@ public abstract class WallProvider { } public void reset() { + this.checkCount.set(0); + this.hardCheckCount.set(0); + this.violationCount.set(0); + this.whiteListHitCount.set(0); + this.blackListHitCount.set(0); this.clearWhiteList(); + this.clearBlackList(); this.functionStats.clear(); this.tableStats.clear(); } @@ -90,6 +97,10 @@ public abstract class WallProvider { return this.tableStats; } + public ConcurrentMap getFunctionStats() { + return this.functionStats; + } + public WallTableStat getTableStat(String tableName) { String lowerCaseName = tableName.toLowerCase(); return getTableStatWithLowerName(lowerCaseName); @@ -131,7 +142,7 @@ public abstract class WallProvider { } public WallSqlStat addWhiteSql(String sql, Map tableStats, - Map functionStats) { + Map functionStats, boolean syntaxError) { lock.writeLock().lock(); try { if (whiteList == null) { @@ -140,7 +151,7 @@ public abstract class WallProvider { WallSqlStat wallStat = whiteList.get(sql); if (wallStat == null) { - wallStat = new WallSqlStat(tableStats, functionStats); + wallStat = new WallSqlStat(tableStats, functionStats, syntaxError); whiteList.put(sql, wallStat); } @@ -151,7 +162,8 @@ public abstract class WallProvider { } public WallSqlStat addBlackSql(String sql, Map tableStats, - Map functionStats, List violations) { + Map functionStats, List violations, + boolean syntaxError) { lock.writeLock().lock(); try { if (blackList == null) { @@ -160,7 +172,7 @@ public abstract class WallProvider { WallSqlStat wallStat = blackList.get(sql); if (wallStat == null) { - wallStat = new WallSqlStat(tableStats, functionStats, violations); + wallStat = new WallSqlStat(tableStats, functionStats, violations, syntaxError); blackList.put(sql, wallStat); } @@ -212,6 +224,17 @@ public abstract class WallProvider { lock.writeLock().unlock(); } } + + public void clearBlackList() { + lock.writeLock().lock(); + try { + if (blackList != null) { + blackList = null; + } + } finally { + lock.writeLock().unlock(); + } + } public WallSqlStat getWhiteSql(String sql) { lock.readLock().lock(); @@ -360,6 +383,10 @@ public abstract class WallProvider { if (sqlStat != null) { whiteListHitCount.incrementAndGet(); sqlStat.incrementAndGetExecuteCount(); + + if (sqlStat.isSyntaxError()) { + syntaxErrrorCount.incrementAndGet(); + } recordStats(sqlStat.getTableStats(), sqlStat.getFunctionStats()); return result; @@ -370,6 +397,12 @@ public abstract class WallProvider { WallSqlStat sqlStat = getBlackSql(sql); if (sqlStat != null) { blackListHitCount.incrementAndGet(); + violationCount.incrementAndGet(); + + if (sqlStat.isSyntaxError()) { + syntaxErrrorCount.incrementAndGet(); + } + sqlStat.incrementAndGetExecuteCount(); recordStats(sqlStat.getTableStats(), sqlStat.getFunctionStats()); List blackViolations = sqlStat.getViolations(); @@ -379,6 +412,8 @@ public abstract class WallProvider { } } + hardCheckCount.incrementAndGet(); + boolean syntaxError = false; try { SQLStatementParser parser = createParser(sql); parser.getLexer().setCommentHandler(WallCommentHandler.instance); @@ -398,6 +433,7 @@ public abstract class WallProvider { incrementCommentDeniedCount(); } catch (ParserException e) { syntaxErrrorCount.incrementAndGet(); + syntaxError = true; if (config.isStrictSyntaxCheck()) { result.getViolations().add(new SyntaxErrorViolation(e, sql)); } @@ -429,11 +465,12 @@ public abstract class WallProvider { violationCount.incrementAndGet(); if (sql.length() < MAX_SQL_LENGTH) { - addBlackSql(sql, context.getTableStats(), context.getFunctionStats(), result.getViolations()); + addBlackSql(sql, context.getTableStats(), context.getFunctionStats(), result.getViolations(), + syntaxError); } } else { if (sql.length() < MAX_SQL_LENGTH) { - addWhiteSql(sql, context.getTableStats(), context.getFunctionStats()); + addWhiteSql(sql, context.getTableStats(), context.getFunctionStats(), syntaxError); } } @@ -514,6 +551,10 @@ public abstract class WallProvider { public long getViolationCount() { return violationCount.get(); } + + public long getHardCheckCount() { + return hardCheckCount.get(); + } public static class WallCommentHandler implements Lexer.CommentHandler { diff --git a/src/main/java/com/alibaba/druid/wall/WallSqlStat.java b/src/main/java/com/alibaba/druid/wall/WallSqlStat.java index 6441df38fe..d431f360f0 100644 --- a/src/main/java/com/alibaba/druid/wall/WallSqlStat.java +++ b/src/main/java/com/alibaba/druid/wall/WallSqlStat.java @@ -32,15 +32,19 @@ public class WallSqlStat { private final Map functionStats; - public WallSqlStat(Map tableStats, Map functionStats){ - this(tableStats, functionStats, Collections. emptyList()); + private final boolean syntaxError; + + public WallSqlStat(Map tableStats, Map functionStats, + boolean syntaxError){ + this(tableStats, functionStats, Collections. emptyList(), syntaxError); } public WallSqlStat(Map tableStats, Map functionStats, - List violations){ + List violations, boolean syntaxError){ this.violations = violations; this.tableStats = tableStats; this.functionStats = functionStats; + this.syntaxError = syntaxError; } public long incrementAndGetExecuteCount() { @@ -54,7 +58,7 @@ public class WallSqlStat { public Map getTableStats() { return tableStats; } - + public Map getFunctionStats() { return functionStats; } @@ -63,4 +67,8 @@ public class WallSqlStat { return violations; } + public boolean isSyntaxError() { + return syntaxError; + } + } diff --git a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java index 3bb1594b8a..e3acf710f6 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -28,6 +28,7 @@ import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLAssignItem; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; @@ -37,6 +38,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLSetStatement; 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.MySqlOutFileExpr; @@ -85,11 +87,6 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi return violations; } - public boolean visit(SQLPropertyExpr x) { - WallVisitorUtils.check(this, x); - return true; - } - public boolean visit(SQLInListExpr x) { WallVisitorUtils.check(this, x); return true; @@ -180,24 +177,64 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi return true; } + public boolean visit(SQLPropertyExpr x) { + if (x.getOwner() instanceof SQLVariantRefExpr) { + SQLVariantRefExpr varExpr = (SQLVariantRefExpr) x.getOwner(); + SQLObject parent = x.getParent(); + String varName = varExpr.getName(); + if (varName.equalsIgnoreCase("@@session") || varName.equalsIgnoreCase("@@global")) { + if (!(parent instanceof SQLSelectItem) && !(parent instanceof SQLAssignItem)) { + violations.add(new IllegalSQLObjectViolation("variable in condition not allow", toSQL(x))); + return false; + } + + if (!checkVar(x.getParent(), x.getName())) { + violations.add(new IllegalSQLObjectViolation("variable not allow : " + x.getName(), toSQL(x))); + } + return false; + } + } + + WallVisitorUtils.check(this, x); + return true; + } + + public boolean checkVar(SQLObject parent, String varName) { + if (varName == null) { + return false; + } + + if (varName.equals("?")) { + return true; + } + + if (!config.isVariantCheck()) { + return true; + } + + if (varName.startsWith("@@")) { + if (!(parent instanceof SQLSelectItem) && !(parent instanceof SQLAssignItem)) { + return false; + } + + varName = varName.substring(2); + } + + if (config.getPermitVariants().contains(varName)) { + return true; + } + + return false; + } + public boolean visit(SQLVariantRefExpr x) { String varName = x.getName(); if (varName == null) { return false; } - if (config.isVariantCheck() && varName.startsWith("@@")) { - if ("@@session".equals(varName)) { - SQLObject parent = x.getParent(); - if (parent instanceof SQLPropertyExpr) { - String propName = ((SQLPropertyExpr) parent).getName(); - if (propName.equals("auto_increment_increment")) { - return false; - } - } - } - - violations.add(new IllegalSQLObjectViolation("global variable", toSQL(x))); + if (!checkVar(x.getParent(), x.getName())) { + violations.add(new IllegalSQLObjectViolation("variable not allow : " + x.getName(), toSQL(x))); } return false; @@ -266,38 +303,43 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(SQLCreateTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(MySqlCreateTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + public boolean visit(SQLAlterTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(MySqlAlterTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + public boolean visit(SQLDropTableStatement x) { WallVisitorUtils.check(this, x); return true; } - + @Override public boolean visit(MySqlDropTableStatement x) { WallVisitorUtils.check(this, x); return true; } + + @Override + public boolean visit(SQLSetStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java index ad630467f0..2aeab53636 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java @@ -36,6 +36,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableStatement; @@ -271,4 +272,9 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi WallVisitorUtils.check(this, x); return true; } + + @Override + public boolean visit(SQLSetStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java index aa54fe7521..2a94ac9e27 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/PGWallVisitor.java @@ -36,6 +36,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; @@ -220,4 +221,9 @@ public class PGWallVisitor extends PGASTVisitorAdapter implements WallVisitor { WallVisitorUtils.check(this, x); return true; } + + @Override + public boolean visit(SQLSetStatement x) { + return false; + } } diff --git a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java index ff8e774367..99e64b4ef5 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -37,6 +37,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; @@ -251,4 +252,9 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements WallVisitorUtils.check(this, x); return true; } + + @Override + public boolean visit(SQLSetStatement x) { + return false; + } } diff --git a/src/main/resources/META-INF/druid/wall/mysql/permit-variant.txt b/src/main/resources/META-INF/druid/wall/mysql/permit-variant.txt new file mode 100644 index 0000000000..3c3efbb201 --- /dev/null +++ b/src/main/resources/META-INF/druid/wall/mysql/permit-variant.txt @@ -0,0 +1,21 @@ +auto_increment_increment +auto_increment_offset +autocommit +automatic_sp_privileges +character_set_client +character_set_database +character_set_connection +character_set_results +character-set-server +collation_connection +collation_database +collation-server +insert_id +last_insert_id +read_only +sql_auto_is_null +sql_big_selects +sql_big_tables +sql_mode +tx_isolation +warning_count \ No newline at end of file diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest34.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest34.java new file mode 100644 index 0000000000..f0b4826a3f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest34.java @@ -0,0 +1,37 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest34 extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT @@sql_big_selects")); // + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var.java new file mode 100644 index 0000000000..7e97f3da8e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var.java @@ -0,0 +1,52 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest_var extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT @@GLOBAL.sql_mode")); // + } + + public void test_true_1() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT @@SESSION.sql_mode;")); // + } + + public void test_false() throws Exception { + Assert.assertFalse(WallUtils.isValidateMySql(// + "SELECT * FROM T WHERE @@SESSION.sql_mode = 'ANSI'")); // + } + + public void test_false_1() throws Exception { + Assert.assertFalse(WallUtils.isValidateMySql(// + "SELECT * FROM T WHERE @@sql_mode = 'ANSI'")); // + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var_autoincrement.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var_autoincrement.java index 174556d987..8cee8795f3 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var_autoincrement.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_var_autoincrement.java @@ -19,7 +19,6 @@ import junit.framework.TestCase; import org.junit.Assert; -import com.alibaba.druid.wall.WallConfig; import com.alibaba.druid.wall.WallUtils; /** @@ -31,10 +30,8 @@ import com.alibaba.druid.wall.WallUtils; */ public class MySqlWallTest_var_autoincrement extends TestCase { - public void test_true() throws Exception { - WallConfig config = new WallConfig(); Assert.assertTrue(WallUtils.isValidateMySql(// - "/* mysql-connector-java-5.? ( Revision: bzr.revision-id ) */SELECT @@session.auto_increment_increment", config)); // + "/* mysql-connector-java-5.? ( Revision: bzr.revision-id ) */SELECT @@session.auto_increment_increment")); // } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDropTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDropTest.java index 86231a8d24..280389b8d6 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDropTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallDropTest.java @@ -19,20 +19,33 @@ import junit.framework.TestCase; import org.junit.Assert; +import com.alibaba.druid.wall.WallConfig; import com.alibaba.druid.wall.WallUtils; /** * 这个场景,被攻击者用于测试当前SQL拥有多少字段 + * * @author wenshao - * */ public class WallDropTest extends TestCase { public void testMySql() throws Exception { - Assert.assertFalse(WallUtils.isValidateMySql("DROP TABLE T1")); + WallConfig config = new WallConfig(); + config.setDropTableAllow(false); + Assert.assertFalse(WallUtils.isValidateMySql("DROP TABLE T1", config)); } - + public void testOracle() throws Exception { - Assert.assertFalse(WallUtils.isValidateOracle("DROP TABLE T1")); + WallConfig config = new WallConfig(); + config.setDropTableAllow(false); + Assert.assertFalse(WallUtils.isValidateOracle("DROP TABLE T1", config)); + } + + public void testMySql_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql("DROP TABLE T1")); + } + + public void testOracle_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateOracle("DROP TABLE T1")); } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_blackList_syntaxError.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_blackList_syntaxError.java new file mode 100644 index 0000000000..cf42c68993 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_blackList_syntaxError.java @@ -0,0 +1,53 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +public class WallStatTest_blackList_syntaxError extends TestCase { + + protected void setUp() throws Exception { + WallContext.clearContext(); + } + + protected void tearDown() throws Exception { + WallContext.clearContext(); + } + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + String sql = "select xx * x *"; + Assert.assertFalse(provider.checkValid(sql)); + { + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(0, tableStat.getSelectCount()); + Assert.assertEquals(0, provider.getBlackListHitCount()); + Assert.assertEquals(0, provider.getWhiteListHitCount()); + Assert.assertEquals(0, provider.getWhiteList().size()); + Assert.assertEquals(1, provider.getBlackList().size()); + Assert.assertEquals(1, provider.getCheckCount()); + Assert.assertEquals(1, provider.getSyntaxErrorCount()); + Assert.assertEquals(1, provider.getHardCheckCount()); + } + + Assert.assertFalse(provider.checkValid(sql)); + { + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(0, tableStat.getSelectCount()); + Assert.assertEquals(1, provider.getBlackListHitCount()); + Assert.assertEquals(0, provider.getWhiteListHitCount()); + Assert.assertEquals(0, provider.getWhiteList().size()); + Assert.assertEquals(1, provider.getBlackList().size()); + Assert.assertEquals(2, provider.getCheckCount()); + Assert.assertEquals(2, provider.getSyntaxErrorCount()); + Assert.assertEquals(1, provider.getHardCheckCount()); + } + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_whiteList_syntaxError.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_whiteList_syntaxError.java new file mode 100644 index 0000000000..555cbaa954 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_whiteList_syntaxError.java @@ -0,0 +1,54 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallContext; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.WallTableStat; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +public class WallStatTest_whiteList_syntaxError extends TestCase { + + protected void setUp() throws Exception { + WallContext.clearContext(); + } + + protected void tearDown() throws Exception { + WallContext.clearContext(); + } + + public void testMySql() throws Exception { + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setStrictSyntaxCheck(false); + + String sql = "select xx * x *"; + Assert.assertTrue(provider.checkValid(sql)); + { + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(0, tableStat.getSelectCount()); + Assert.assertEquals(0, provider.getBlackListHitCount()); + Assert.assertEquals(0, provider.getWhiteListHitCount()); + Assert.assertEquals(1, provider.getWhiteList().size()); + Assert.assertEquals(0, provider.getBlackList().size()); + Assert.assertEquals(1, provider.getCheckCount()); + Assert.assertEquals(1, provider.getSyntaxErrorCount()); + Assert.assertEquals(1, provider.getHardCheckCount()); + } + + Assert.assertTrue(provider.checkValid(sql)); + { + WallTableStat tableStat = provider.getTableStat("t"); + Assert.assertEquals(0, tableStat.getSelectCount()); + Assert.assertEquals(0, provider.getBlackListHitCount()); + Assert.assertEquals(1, provider.getWhiteListHitCount()); + Assert.assertEquals(1, provider.getWhiteList().size()); + Assert.assertEquals(0, provider.getBlackList().size()); + Assert.assertEquals(2, provider.getCheckCount()); + Assert.assertEquals(2, provider.getSyntaxErrorCount()); + Assert.assertEquals(1, provider.getHardCheckCount()); + } + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest.java index 02312a278b..1d2b179e5a 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallTruncateTest.java @@ -25,18 +25,30 @@ import com.alibaba.druid.wall.WallUtils; public class WallTruncateTest extends TestCase { private String sql = "TRUNCATE TABLE T1"; - private WallConfig config = new WallConfig(); protected void setUp() throws Exception { //config.setTruncateAllow(true); } public void testMySql() throws Exception { - Assert.assertFalse(WallUtils.isValidateMySql(sql, config)); + WallConfig config = new WallConfig(); + Assert.assertTrue(WallUtils.isValidateMySql(sql, config)); } public void testORACLE() throws Exception { - + WallConfig config = new WallConfig(); + Assert.assertTrue(WallUtils.isValidateOracle(sql, config)); + } + + public void testMySql_false() throws Exception { + WallConfig config = new WallConfig(); + config.setTruncateAllow(false); + Assert.assertFalse(WallUtils.isValidateMySql(sql, config)); + } + + public void testORACLE_false() throws Exception { + WallConfig config = new WallConfig(); + config.setTruncateAllow(false); Assert.assertFalse(WallUtils.isValidateOracle(sql, config)); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test.java new file mode 100644 index 0000000000..b749baa9cf --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test.java @@ -0,0 +1,42 @@ +/* + * 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.sql.mysql; + + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; + +public class MySqlError_test extends MysqlTest { + + public void test_0() throws Exception { + String sql = "insert into userdetectitem26 (nick,volume) values(?,?) " + // + "ON DUPLICATE KEY UPDATE title = ?,picURL = ?,scoreExceed = ?,score="; + + Exception error = null; + + try { + MySqlStatementParser parser = new MySqlStatementParser(sql); + parser.parseStatementList(); + } catch (Exception e) { + error = e; + } + + Assert.assertNotNull(error); + Assert.assertEquals("EOF, score=", error.getMessage()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_1.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_1.java new file mode 100644 index 0000000000..59b5226fa5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_1.java @@ -0,0 +1,40 @@ +/* + * 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.sql.mysql; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; + +public class MySqlError_test_1 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "SELECT * FROM pp_items WHERE uid= ORDER BY id DESC LIMIT ?,?"; + Exception error = null; + + try { + MySqlStatementParser parser = new MySqlStatementParser(sql); + parser.parseStatementList(); + } catch (Exception e) { + error = e; + } + + Assert.assertNotNull(error); +// error.printStackTrace(); + Assert.assertEquals("ERROR. token : ORDER, pos : 39", error.getMessage()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_2.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_2.java new file mode 100644 index 0000000000..f5761914a2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_2.java @@ -0,0 +1,40 @@ +/* + * 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.sql.mysql; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; + +public class MySqlError_test_2 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "Describe sdb_goods free_postage"; + Exception error = null; + + try { + MySqlStatementParser parser = new MySqlStatementParser(sql); + parser.parseStatementList(); + } catch (Exception e) { + error = e; + } + + Assert.assertNotNull(error); +// error.printStackTrace(); + Assert.assertEquals("syntax error, IDENTIFIER free_postage, pos 31", error.getMessage()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_3.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_3.java new file mode 100644 index 0000000000..511cba095f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlError_test_3.java @@ -0,0 +1,44 @@ +/* + * 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.sql.mysql; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; + +public class MySqlError_test_3 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "SELECT count(*) AS num FROM sdb_products AS P" + // + " LEFT JOIN sdb_goods AS G ON G.goods_id = P.goods_id" + // + " LEFT JOIN sdb_goods_cat AS C ON C.cat_id = G.cat_id" + // + " LEFT JOIN sdb_brand AS B ON B.brand_id = G.brand_id" + // + " WHERE P.disabled = ? AND P.op_status = LIMIT ?, ?"; + Exception error = null; + + try { + MySqlStatementParser parser = new MySqlStatementParser(sql); + parser.parseStatementList(); + } catch (Exception e) { + error = e; + } + + Assert.assertNotNull(error); +// error.printStackTrace(); + Assert.assertEquals("syntax error, QUES LIMIT, pos 248", error.getMessage()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_9.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_9.java new file mode 100644 index 0000000000..10a652ff71 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_9.java @@ -0,0 +1,61 @@ +/* + * 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.sql.mysql; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class MySqlSelectTest_9 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "SELECT `group`.* FROM `group` WHERE (group.group_id=159754)"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + SQLSelectStatement selectStmt = (SQLSelectStatement) stmt; + + SQLSelect select = selectStmt.getSelect(); + Assert.assertNotNull(select.getQuery()); + MySqlSelectQueryBlock queryBlock = (MySqlSelectQueryBlock) select.getQuery(); + Assert.assertNull(queryBlock.getOrderBy()); + + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(2, visitor.getColumns().size()); + Assert.assertEquals(1, visitor.getConditions().size()); + Assert.assertEquals(0, visitor.getOrderByColumns().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("group"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlShowTest_table.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlShowTest_table.java new file mode 100644 index 0000000000..9eb377e788 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlShowTest_table.java @@ -0,0 +1,51 @@ +/* + * 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.sql.mysql; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; + +public class MySqlShowTest_table extends MysqlTest { + + public void test_0() throws Exception { + String sql = "SHOW FULL TABLES FROM sonar LIKE 'a'"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + Assert.assertEquals(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + Assert.assertEquals(0, visitor.getOrderByColumns().size()); + + // Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("mytable"))); + } +}