From eddb42ae53f6c699a7b82c5fe2756388773bd473 Mon Sep 17 00:00:00 2001 From: wenshao Date: Thu, 11 Apr 2013 15:38:13 +0800 Subject: [PATCH] improve wall filter --- .../alibaba/druid/pool/DruidDataSource.java | 4 + .../druid/sql/ast/expr/SQLInSubQueryExpr.java | 3 + .../druid/sql/ast/expr/SQLPropertyExpr.java | 7 +- .../sql/dialect/mysql/parser/MySqlLexer.java | 18 ++-- .../alibaba/druid/wall/WallCheckResult.java | 11 ++- .../com/alibaba/druid/wall/WallConfig.java | 2 - .../com/alibaba/druid/wall/WallContext.java | 61 +++++++++++- .../com/alibaba/druid/wall/WallProvider.java | 77 ++++++++++----- .../com/alibaba/druid/wall/WallSqlStat.java | 20 +++- .../druid/wall/spi/MySqlWallVisitor.java | 27 +++-- .../druid/wall/spi/WallVisitorUtils.java | 98 ++++++++++++++++--- .../druid/wall/violation/ErrorCode.java | 2 + .../bvt/filter/wall/MySqlWallTest62.java | 4 +- .../bvt/filter/wall/MySqlWallTest65.java | 2 +- .../bvt/filter/wall/MySqlWallTest66.java | 54 ++++++++++ .../bvt/filter/wall/MySqlWallTest67.java | 54 ++++++++++ .../bvt/filter/wall/MySqlWallTest68.java | 45 +++++++++ .../bvt/filter/wall/MySqlWallTest69.java | 44 +++++++++ .../bvt/filter/wall/MySqlWallTest70.java | 45 +++++++++ .../bvt/filter/wall/MySqlWallTest71.java | 45 +++++++++ .../bvt/filter/wall/MySqlWallTest72.java | 45 +++++++++ .../bvt/filter/wall/MySqlWallTest73.java | 52 ++++++++++ .../bvt/filter/wall/MySqlWallTest74.java | 54 ++++++++++ .../bvt/filter/wall/MySqlWallTest75.java | 45 +++++++++ .../bvt/filter/wall/WallStatTest_statMap.java | 5 + .../alibaba/druid/mysql/QueryTimeoutTest.java | 56 +++++++++++ .../alibaba/druid/pool/QueryTimeoutTest.java | 56 +++++++++++ .../druid/pool/oracle/QueryTimeoutTest.java | 79 +++++++++++++++ 28 files changed, 946 insertions(+), 69 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest66.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest67.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest68.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest69.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest70.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest71.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest72.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest73.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest74.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest75.java create mode 100644 src/test/java/com/alibaba/druid/mysql/QueryTimeoutTest.java create mode 100644 src/test/java/com/alibaba/druid/pool/QueryTimeoutTest.java create mode 100644 src/test/java/com/alibaba/druid/pool/oracle/QueryTimeoutTest.java diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index eff24fb1c9..43562dd919 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -890,6 +890,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat return; } + if (pooledConnection.getOwnerThread() != Thread.currentThread()) { + throw new SQLException("closed error, get/close not same thread"); + } + final Connection physicalConnection = holder.getConnection(); if (pooledConnection.isTraceEnable()) { diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java index a78cec4c0a..3652f88821 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java @@ -60,6 +60,9 @@ public class SQLInSubQueryExpr extends SQLExprImpl implements Serializable { } public void setSubQuery(SQLSelect subQuery) { + if (subQuery != null) { + subQuery.setParent(this); + } this.subQuery = subQuery; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java index 69b0ad7fa3..135ad4bc2a 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java @@ -28,10 +28,7 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName { private String name; public SQLPropertyExpr(SQLExpr owner, String name){ - if (owner != null) { - owner.setParent(this); - } - this.owner = owner; + setOwner(owner); this.name = name; } @@ -53,7 +50,7 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName { } this.owner = owner; } - + public String getName() { return this.name; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index b56cacc88a..cf76fec9a5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -363,7 +363,7 @@ public class MySqlLexer extends Lexer { return; } if (ch == '*' && charAt(pos + 1) == '/') { - bufPos += 2; + bufPos += 3; scanChar(); scanChar(); break; @@ -393,11 +393,6 @@ public class MySqlLexer extends Lexer { return; } - - if (!isAllowComment()) { - throw new NotAllowCommentException(); - } - if (ch == '/' || ch == '-') { scanChar(); bufPos++; @@ -425,8 +420,17 @@ public class MySqlLexer extends Lexer { bufPos++; } - stringVal = subString(mark + 1, bufPos); + stringVal = subString(mark, bufPos + 1); token = Token.LINE_COMMENT; + + if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { + return; + } + + if (!isAllowComment()) { + throw new NotAllowCommentException(); + } + return; } } diff --git a/src/main/java/com/alibaba/druid/wall/WallCheckResult.java b/src/main/java/com/alibaba/druid/wall/WallCheckResult.java index c7fc201954..42982fd1bf 100644 --- a/src/main/java/com/alibaba/druid/wall/WallCheckResult.java +++ b/src/main/java/com/alibaba/druid/wall/WallCheckResult.java @@ -32,6 +32,8 @@ public class WallCheckResult { private final boolean syntaxError; + private final WallSqlStat sqlStat; + public WallCheckResult(){ this(null); } @@ -50,15 +52,17 @@ public class WallCheckResult { statementList = stmtList; syntaxError = false; } + this.sqlStat = sqlStat; } public WallCheckResult(WallSqlStat sqlStat){ this(sqlStat, Collections. emptyList()); } - public WallCheckResult(List violations, Map tableStats, + public WallCheckResult(WallSqlStat sqlStat, List violations, Map tableStats, Map functionStats, List statementList, boolean syntaxError){ + this.sqlStat = sqlStat; this.tableStats = tableStats; this.violations = violations; this.functionStats = functionStats; @@ -85,4 +89,9 @@ public class WallCheckResult { public boolean isSyntaxError() { return syntaxError; } + + + public WallSqlStat getSqlStat() { + return sqlStat; + } } diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index 868a0628b4..8aa8883df9 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -118,8 +118,6 @@ public class WallConfig implements WallConfigMBean { this.limitZeroAllow = limitZero; } - - public boolean isConditionAndAlwayTrueAllow() { return conditionAndAlwayTrueAllow; } diff --git a/src/main/java/com/alibaba/druid/wall/WallContext.java b/src/main/java/com/alibaba/druid/wall/WallContext.java index d8a6ea6f09..63374e5624 100644 --- a/src/main/java/com/alibaba/druid/wall/WallContext.java +++ b/src/main/java/com/alibaba/druid/wall/WallContext.java @@ -20,12 +20,17 @@ import java.util.Map; public class WallContext { - private final static ThreadLocal contextLocal = new ThreadLocal(); + private final static ThreadLocal contextLocal = new ThreadLocal(); private WallSqlStat sqlStat; private Map tableStats; private Map functionStats; private final String dbType; + private int commentCount; + private int warnnings = 0; + private int unionWarnnings = 0; + private int updateNoneConditionWarnnings = 0; + private int deleteNoneConditionWarnnings = 0; public WallContext(String dbType){ this.dbType = dbType; @@ -92,7 +97,7 @@ public class WallContext { public static void clearContext() { contextLocal.remove(); } - + public static void setContext(WallContext context) { contextLocal.set(context); } @@ -117,4 +122,56 @@ public class WallContext { return dbType; } + public int getCommentCount() { + return commentCount; + } + + public void incrementCommentCount() { + if (this.commentCount == 0) { + this.warnnings++; + } + this.commentCount++; + } + + public int getWarnnings() { + return warnnings; + } + + public void incrementWarnnings() { + this.warnnings++; + } + + public int getUnionWarnnings() { + return unionWarnnings; + } + + public void incrementUnionWarnnings() { + if (this.unionWarnnings == 0) { + this.incrementWarnnings(); + } + this.unionWarnnings++; + } + + public int getUpdateNoneConditionWarnnings() { + return updateNoneConditionWarnnings; + } + + public void incrementUpdateNoneConditionWarnnings() { + if (this.updateNoneConditionWarnnings == 0) { + this.incrementWarnnings(); + } + this.updateNoneConditionWarnnings++; + } + + public int getDeleteNoneConditionWarnnings() { + return deleteNoneConditionWarnnings; + } + + public void incrementDeleteNoneConditionWarnnings() { + if (this.deleteNoneConditionWarnnings == 0) { + this.incrementWarnnings(); + } + this.deleteNoneConditionWarnnings++; + } + } diff --git a/src/main/java/com/alibaba/druid/wall/WallProvider.java b/src/main/java/com/alibaba/druid/wall/WallProvider.java index 4544def8af..fede94a6da 100644 --- a/src/main/java/com/alibaba/druid/wall/WallProvider.java +++ b/src/main/java/com/alibaba/druid/wall/WallProvider.java @@ -45,32 +45,33 @@ public abstract class WallProvider { private LRUCache whiteList; - private int MAX_SQL_LENGTH = 2048; // 1k + private int MAX_SQL_LENGTH = 2048; // 1k - private int whiteSqlMaxSize = 500; // 1k + private int whiteSqlMaxSize = 500; // 1k private LRUCache blackList; - private int blackSqlMaxSize = 100; // 1k + private int blackSqlMaxSize = 100; // 1k protected final WallConfig config; - private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - private static final ThreadLocal privileged = new ThreadLocal(); + private static final ThreadLocal privileged = new ThreadLocal(); - private final ConcurrentMap functionStats = new ConcurrentHashMap(); - private final ConcurrentMap tableStats = new ConcurrentHashMap(); + private final ConcurrentMap functionStats = new ConcurrentHashMap(); + private final ConcurrentMap tableStats = new ConcurrentHashMap(); - public final WallDenyStat commentDeniedStat = new WallDenyStat(); + public final WallDenyStat commentDeniedStat = new WallDenyStat(); - 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(); - protected final AtomicLong violationCount = new AtomicLong(); + 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(); + protected final AtomicLong violationCount = new AtomicLong(); + protected final AtomicLong violationEffectRowCount = new AtomicLong(); public WallProvider(WallConfig config){ this.config = config; @@ -215,7 +216,7 @@ public abstract class WallProvider { return Collections. unmodifiableSet(hashSet); } - + public List> getBlackListStat() { List> map = new ArrayList>(); lock.readLock().lock(); @@ -223,23 +224,24 @@ public abstract class WallProvider { if (blackList != null) { for (Map.Entry entry : this.blackList.entrySet()) { WallSqlStat sqlStat = entry.getValue(); - + Map sqlStatMap = new LinkedHashMap(); sqlStatMap.put("sql", entry.getKey()); sqlStatMap.put("executeCount", sqlStat.getExecuteCount()); - + sqlStatMap.put("effectRowCount", sqlStat.getEffectRowCount()); + List violations = sqlStat.getViolations(); if (violations.size() > 0) { sqlStatMap.put("violationMessage", violations.get(0).getMessage()); } - + map.add(sqlStatMap); } } } finally { lock.readLock().unlock(); } - + return map; } @@ -342,7 +344,7 @@ public abstract class WallProvider { if (schemaName == null) { return true; } - + if (!this.config.isSchemaCheck()) { return true; } @@ -432,7 +434,8 @@ public abstract class WallProvider { final Token lastToken = parser.getLexer().token(); if (lastToken != Token.EOF) { - violations.add(new IllegalSQLObjectViolation(ErrorCode.SYNTAX_ERROR, "not terminal sql, token " + lastToken, sql)); + violations.add(new IllegalSQLObjectViolation(ErrorCode.SYNTAX_ERROR, "not terminal sql, token " + + lastToken, sql)); } } catch (NotAllowCommentException e) { violations.add(new SyntaxErrorViolation(e, sql)); @@ -466,6 +469,18 @@ public abstract class WallProvider { violations.addAll(visitor.getViolations()); } + if (context != null && context.getWarnnings() >= 2) { + if (context.getDeleteNoneConditionWarnnings() > 0) { + violations.add(new IllegalSQLObjectViolation(ErrorCode.NONE_CONDITION, "delete none condition", sql)); + } else if (context.getUpdateNoneConditionWarnnings() > 0) { + violations.add(new IllegalSQLObjectViolation(ErrorCode.NONE_CONDITION, "update none condition", sql)); + } else if (context.getCommentCount() > 0) { + violations.add(new IllegalSQLObjectViolation(ErrorCode.COMMIT_NOT_ALLOW, "comment not allow", sql)); + } else { + violations.add(new IllegalSQLObjectViolation(ErrorCode.COMPOUND, "multi-warnnings", sql)); + } + } + WallSqlStat sqlStat = null; if (violations.size() > 0) { violationCount.incrementAndGet(); @@ -492,7 +507,7 @@ public abstract class WallProvider { return new WallCheckResult(sqlStat, statementList); } - return new WallCheckResult(violations, tableStats, functionStats, statementList, syntaxError); + return new WallCheckResult(sqlStat, violations, tableStats, functionStats, statementList, syntaxError); } private WallCheckResult checkWhiteAndBlackList(String sql) { @@ -609,6 +624,14 @@ public abstract class WallProvider { public long getHardCheckCount() { return hardCheckCount.get(); } + + public long getViolationEffectRowCount() { + return violationEffectRowCount.get(); + } + + public void addViolationEffectRowCount(long rowCount) { + violationEffectRowCount.addAndGet(rowCount); + } public static class WallCommentHandler implements Lexer.CommentHandler { @@ -636,7 +659,12 @@ public abstract class WallProvider { default: break; } - + + WallContext context = WallContext.current(); + if (context != null) { + context.incrementCommentCount(); + } + return false; } } @@ -647,6 +675,7 @@ public abstract class WallProvider { info.put("checkCount", this.getCheckCount()); info.put("hardCheckCount", this.getHardCheckCount()); info.put("violationCount", this.getViolationCount()); + info.put("violationEffectRowCount", this.getViolationEffectRowCount()); info.put("blackListHitCount", this.getBlackListHitCount()); info.put("blackListSize", this.getBlackList().size()); info.put("whiteListHitCount", this.getWhiteListHitCount()); diff --git a/src/main/java/com/alibaba/druid/wall/WallSqlStat.java b/src/main/java/com/alibaba/druid/wall/WallSqlStat.java index 8dede70458..50a87fc44e 100644 --- a/src/main/java/com/alibaba/druid/wall/WallSqlStat.java +++ b/src/main/java/com/alibaba/druid/wall/WallSqlStat.java @@ -23,9 +23,13 @@ import java.util.concurrent.atomic.AtomicLongFieldUpdater; public class WallSqlStat { private volatile long executeCount; + private volatile long effectRowCount; - final static AtomicLongFieldUpdater executeCountUpdater = AtomicLongFieldUpdater.newUpdater(WallSqlStat.class, - "executeCount"); + final static AtomicLongFieldUpdater executeCountUpdater = AtomicLongFieldUpdater.newUpdater(WallSqlStat.class, + "executeCount"); + final static AtomicLongFieldUpdater effectRowCountUpdater = AtomicLongFieldUpdater.newUpdater(WallSqlStat.class, + "effectRowCount"); + private final Map tableStats; private final List violations; @@ -54,6 +58,18 @@ public class WallSqlStat { public long getExecuteCount() { return executeCount; } + + public long incrementAndGetEffectRowCount() { + return effectRowCountUpdater.incrementAndGet(this); + } + + public long addAndGetEffectRowCount(long delta) { + return effectRowCountUpdater.addAndGet(this, delta); + } + + public long getEffectRowCount() { + return effectRowCount; + } public Map getTableStats() { return tableStats; 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 87b1a1d87a..8bd4ce48a1 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -165,7 +165,8 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi @Override public boolean visit(SQLSelectStatement x) { if (!config.isSelelctAllow()) { - this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "select not allow", this.toSQL(x))); + this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "select not allow", + this.toSQL(x))); return false; } @@ -175,9 +176,18 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi @Override public boolean visit(Limit x) { if (x.getRowCount() instanceof SQLNumericLiteralExpr) { + WallContext context = WallContext.current(); + int rowCount = ((SQLNumericLiteralExpr) x.getRowCount()).getNumber().intValue(); - if (rowCount == 0 && !provider.getConfig().isLimitZeroAllow()) { - this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.LIMIT_ZERO, "limit row 0", this.toSQL(x))); + if (rowCount == 0) { + if (context != null) { + context.incrementWarnnings(); + } + + if (!provider.getConfig().isLimitZeroAllow()) { + this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.LIMIT_ZERO, "limit row 0", + this.toSQL(x))); + } } } return true; @@ -190,14 +200,16 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi String varName = varExpr.getName(); if (varName.equalsIgnoreCase("@@session") || varName.equalsIgnoreCase("@@global")) { if (!(parent instanceof SQLSelectItem) && !(parent instanceof SQLAssignItem)) { - violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable in condition not allow", toSQL(x))); + violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, + "variable in condition not allow", toSQL(x))); return false; } if (!checkVar(x.getParent(), x.getName())) { boolean isTop = WallVisitorUtils.isTopNoneFromSelect(x); if (!isTop) { - violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + x.getName(), toSQL(x))); + violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + + x.getName(), toSQL(x))); } } return false; @@ -245,7 +257,8 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi if (varName.startsWith("@@") && !checkVar(x.getParent(), x.getName())) { boolean isTop = WallVisitorUtils.isTopNoneFromSelect(x); if (!isTop) { - violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + x.getName(), toSQL(x))); + violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + + x.getName(), toSQL(x))); } } @@ -364,7 +377,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi public boolean visit(SQLCallStatement x) { return false; } - + @Override public boolean visit(MySqlShowCreateTableStatement x) { String tableName = ((SQLName) x.getName()).getSimleName(); 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 8e5195e51c..b50016ceba 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -70,6 +70,7 @@ import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.ast.statement.SQLUseStatement; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; @@ -235,10 +236,24 @@ public class WallVisitorUtils { addViolation(visitor, ErrorCode.INSERT_NOT_ALLOW, "delete not allow", x); return; } + + boolean hasUsing = false; + + if (x instanceof MySqlDeleteStatement) { + hasUsing = ((MySqlDeleteStatement) x).getUsing() != null; + } - if (x.getWhere() == null && config.isDeleteWhereNoneCheck()) { - addViolation(visitor, ErrorCode.NONE_CONDITION, "delete none condition not allow", x); - return; + boolean isJoinTableSource = x.getTableSource() instanceof SQLJoinTableSource; + if (x.getWhere() == null && (!hasUsing) && !isJoinTableSource) { + WallContext context = WallContext.current(); + if (context != null) { + context.incrementDeleteNoneConditionWarnnings(); + } + + if (config.isDeleteWhereNoneCheck()) { + addViolation(visitor, ErrorCode.NONE_CONDITION, "delete none condition not allow", x); + return; + } } if (Boolean.TRUE == getConditionValue(visitor, x.getWhere(), config.isDeleteWhereAlwayTrueCheck())) { @@ -430,16 +445,23 @@ public class WallVisitorUtils { return; } - if (x.getWhere() == null && config.isUpdateWhereNoneCheck()) { - if (x instanceof MySqlUpdateStatement) { - MySqlUpdateStatement mysqlUpdate = (MySqlUpdateStatement) x; - if (mysqlUpdate.getLimit() == null) { + if (x.getWhere() == null) { + WallContext context = WallContext.current(); + if (context != null) { + context.incrementUpdateNoneConditionWarnnings(); + } + + if (config.isUpdateWhereNoneCheck()) { + if (x instanceof MySqlUpdateStatement) { + MySqlUpdateStatement mysqlUpdate = (MySqlUpdateStatement) x; + if (mysqlUpdate.getLimit() == null) { + addViolation(visitor, ErrorCode.NONE_CONDITION, "update none condition not allow", x); + return; + } + } else { addViolation(visitor, ErrorCode.NONE_CONDITION, "update none condition not allow", x); return; } - } else { - addViolation(visitor, ErrorCode.NONE_CONDITION, "update none condition not allow", x); - return; } } @@ -643,6 +665,13 @@ public class WallVisitorUtils { final Object value = getValue(x); final WallConditionContext current = wallConditionContextLocal.get(); + WallContext context = WallContext.current(); + if (context != null) { + if (current.hasPartAlwayTrue() || Boolean.TRUE == value) { + context.incrementWarnnings(); + } + } + if (current.hasPartAlwayTrue() && alwayTrueCheck && !visitor.getConfig().isConditionAndAlwayTrueAllow()) { addViolation(visitor, ErrorCode.ALWAY_TRUE, "part alway true condition not allow", x); } @@ -910,7 +939,41 @@ public class WallVisitorUtils { boolean topSelectStatement = isTopSelectStatement(x); if (!topSelectStatement) { - addViolation(visitor, ErrorCode.SCHEMA_DENY, "deny schema : " + owner, x); + SQLObject parent = x.getParent(); + while (parent != null && !(parent instanceof SQLStatement)) { + parent = parent.getParent(); + } + + boolean sameToTopSelectSchema = false; + if (parent instanceof SQLSelectStatement) { + SQLSelectStatement selectStmt = (SQLSelectStatement) parent; + SQLSelectQuery query = selectStmt.getSelect().getQuery(); + if (query instanceof SQLSelectQueryBlock) { + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; + SQLTableSource from = queryBlock.getFrom(); + + while (from instanceof SQLJoinTableSource) { + from = ((SQLJoinTableSource) from).getLeft(); + } + if (from instanceof SQLExprTableSource) { + SQLExpr expr = ((SQLExprTableSource) from).getExpr(); + if (expr instanceof SQLPropertyExpr) { + SQLExpr schemaExpr = ((SQLPropertyExpr) expr).getOwner(); + if (schemaExpr instanceof SQLIdentifierExpr) { + String schema = ((SQLIdentifierExpr) schemaExpr).getName(); + schema = form(schema); + if (schema.equalsIgnoreCase(owner)) { + sameToTopSelectSchema = true; + } + } + } + } + } + } + + if (!sameToTopSelectSchema) { + addViolation(visitor, ErrorCode.SCHEMA_DENY, "deny schema : " + owner, x); + } } return true; } @@ -1026,10 +1089,6 @@ public class WallVisitorUtils { return; } - if (!visitor.getConfig().isSelectUnionCheck()) { - return; - } - if (WallVisitorUtils.queryBlockFromIsNull(x.getLeft()) || WallVisitorUtils.queryBlockFromIsNull(x.getRight())) { boolean isTopUpdateStatement = false; SQLObject selectParent = x.getParent(); @@ -1047,8 +1106,15 @@ public class WallVisitorUtils { if (isTopUpdateStatement) { return; } + + WallContext context = WallContext.current(); + if (context != null) { + context.incrementUnionWarnnings(); + } - addViolation(visitor, ErrorCode.UNION, "union query not contains 'from clause'", x); + if (visitor.getConfig().isSelectUnionCheck()) { + addViolation(visitor, ErrorCode.UNION, "union query not contains 'from clause'", x); + } } } diff --git a/src/main/java/com/alibaba/druid/wall/violation/ErrorCode.java b/src/main/java/com/alibaba/druid/wall/violation/ErrorCode.java index bb08c0f863..e16bc05600 100644 --- a/src/main/java/com/alibaba/druid/wall/violation/ErrorCode.java +++ b/src/main/java/com/alibaba/druid/wall/violation/ErrorCode.java @@ -68,5 +68,7 @@ public interface ErrorCode { public final static int READ_ONLY = 4000; public final static int UNION = 5000; + public final static int COMPOUND = 8000; + public final static int OTHER = 9999; } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest62.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest62.java index 2f54b0b26b..bef7784adc 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest62.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest62.java @@ -35,7 +35,7 @@ public class MySqlWallTest62 extends TestCase { WallProvider provider = new MySqlWallProvider(); provider.getConfig().setSchemaCheck(true); - Assert.assertTrue(provider.checkValid(// + Assert.assertFalse(provider.checkValid(// "select temp.*, u.CanComment, u.CanBeShared, u.CanForward, COALESCE(b.UserID,0) as isBlocked" + // " , COALESCE(f.UserID,0) as Followed, COALESCE(ff.UserID,0) as IsFollowed" + // " , COALESCE(ul.UserID,0) as liked, COALESCE(fff.UserID,0) as RIsFollowed " + // @@ -48,7 +48,7 @@ public class MySqlWallTest62 extends TestCase { "left join Fans as fff ON fff.FansID = 294765 and fff.UserID = temp.RUserID " + // "left join UserLikes as ul on ul.PicID = temp.PicID and ul.UserID = 294765")); - Assert.assertEquals(1, provider.getTableStats().size()); + Assert.assertEquals(4, provider.getTableStats().size()); } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest65.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest65.java index e48044a385..42f1860525 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest65.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest65.java @@ -38,7 +38,7 @@ public class MySqlWallTest65 extends TestCase { Assert.assertFalse(provider.checkValid(// "SELECT email, passwd, login_id, full_name" + " FROM members" + - " WHERE member_id = 3 AND 0<(SELECT COUNT(*) FROM tabname);'")); + " WHERE member_id = 3 AND 0<(SELECT COUNT(*) FROM tabname);")); Assert.assertEquals(2, provider.getTableStats().size()); } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest66.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest66.java new file mode 100644 index 0000000000..288ff03c5d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest66.java @@ -0,0 +1,54 @@ +/* + * 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.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest66 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setSchemaCheck(true); + + Assert.assertTrue(provider.checkValid(// + "SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA " + // + "FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND FILE_NAME IS NOT NULL " + // + "AND LOGFILE_GROUP_NAME IN (" + // + " SELECT DISTINCT LOGFILE_GROUP_NAME FROM INFORMATION_SCHEMA.FILES " + // + " WHERE FILE_TYPE = 'DATAFILE' " + // + " AND TABLESPACE_NAME IN (" + // + " SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS " + // + " WHERE TABLE_SCHEMA IN ('stat'))" + // + ") " + // + "GROUP BY LOGFILE_GROUP_NAME, FILE_NAME, ENGINE " + // + "ORDER BY LOGFILE_GROUP_NAME")); + + Assert.assertEquals(2, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest67.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest67.java new file mode 100644 index 0000000000..22c0126a71 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest67.java @@ -0,0 +1,54 @@ +/* + * 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.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest67 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setSchemaCheck(true); + + Assert.assertTrue(provider.checkValid(// + "SELECT c.table_name, column_name, column_type, is_nullable, column_key" + // + " , column_default, extra, collation_name, character_set_name, column_comment " + // + "FROM information_schema.columns c " + // + "INNER JOIN (" + // + " SELECT table_schema, table_name " + // + " FROM information_schema.tables " + // + " WHERE LOWER(table_schema) = LOWER('sp5035d3d0b2d4a')" + // + ") t ON t.table_name COLLATE utf8_bin = c.table_name COLLATE utf8_bin " + // + "WHERE LOWER(c.table_schema) = LOWER('sp5035d3d0b2d4a') " + // + " AND ('Y' = '' OR LOWER(c.table_name) IN ('leader01_weibo')) " + // + "ORDER BY t.table_name")); + + Assert.assertEquals(2, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest68.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest68.java new file mode 100644 index 0000000000..cccc1e77ad --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest68.java @@ -0,0 +1,45 @@ +/* + * 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.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest68 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setSchemaCheck(true); + + Assert.assertTrue(provider.checkValid(// + "SELECT * FROM `information_schema`.`ROUTINES` " + // + "WHERE `information_schema`.`ROUTINES`.`ROUTINE_SCHEMA` = 'mzsg_g001'")); + + Assert.assertEquals(1, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest69.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest69.java new file mode 100644 index 0000000000..0dbb3739c4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest69.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.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest69 extends TestCase { + + public void test_true() throws Exception { + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setCommentAllow(true); + + Assert.assertTrue(provider.checkValid(// + "select * from T--")); + + Assert.assertEquals(1, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest70.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest70.java new file mode 100644 index 0000000000..49be710548 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest70.java @@ -0,0 +1,45 @@ +/* + * 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.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest70 extends TestCase { + + public void test_true() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + provider.getConfig().setCommentAllow(true); + + Assert.assertTrue(provider.checkValid(// + "select * from T/**/")); + + Assert.assertEquals(1, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest71.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest71.java new file mode 100644 index 0000000000..3eddec72d8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest71.java @@ -0,0 +1,45 @@ +/* + * 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.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest71 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + provider.getConfig().setCommentAllow(true); + + Assert.assertFalse(provider.checkValid(// + "update order_return set return_goods_money =0.00 ,return_other_money = 8--149.00, return_total_fee = ifnull(return_shipping,0)+ifnull(return_other_discount,0)+0.00--149.00-0.00,return_goods_amount=1,return_real_money=0.00 where id=1319")); + + Assert.assertEquals(1, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest72.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest72.java new file mode 100644 index 0000000000..c2ec53d1e1 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest72.java @@ -0,0 +1,45 @@ +/* + * 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.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest72 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + provider.getConfig().setCommentAllow(true); + + Assert.assertFalse(provider.checkValid(// + "select * from t /**/ where 1=1")); + + Assert.assertEquals(1, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest73.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest73.java new file mode 100644 index 0000000000..0fd18a4aad --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest73.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.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest73 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + provider.getConfig().setCommentAllow(true); + + Assert.assertTrue(provider.checkValid(// + "DELETE FROM D1 USING PCHS_DETAIL D1 " + // + " INNER JOIN (" + // + " SELECT D.DETAIL_UID " + // + " FROM PCHS_DETAIL D " + // + " INNER JOIN PCHS_BILL B ON D.BILL_UID=B.BILL_UID " + // + " WHERE B.COM_UID='0892E8A38EF83AB6B9E25C25D8085486' " + // + " LIMIT 1000 " + // + " ) D2 ON D1.DETAIL_UID=D2.DETAIL_UID")); + + Assert.assertEquals(3, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest74.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest74.java new file mode 100644 index 0000000000..e62e7c09e6 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest74.java @@ -0,0 +1,54 @@ +/* + * 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.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest74 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + provider.getConfig().setCommentAllow(true); + + Assert.assertTrue(provider.checkValid(// + "select _t0.`ownUser` as _c0, _t0.`showTime` as _c1, _t0.`showType` as _c2, " + // + " _t0.`itemId` as _c3, _t0.`queueId` as _c4 " + // + "from `itemshow_queue` as _t0 " + // + "where ( _t0.`isShowed` = 'F' and _t0.`showTime` <= ? ) " + // + " and _t0.`ownUser` in ( " + // + " select _t0.`userId` as _c0 from `users_top` as _t0 " + // + " where ( 1 = 1 ) " + // + " ) " + // + "order by _t0.`showTime` asc " + // + "limit 1000 offset 8000")); + + Assert.assertEquals(2, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest75.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest75.java new file mode 100644 index 0000000000..b2cec6a48c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest75.java @@ -0,0 +1,45 @@ +/* + * 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.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest75 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + provider.getConfig().setCommentAllow(true); + + Assert.assertFalse(provider.checkValid(// + "UPDATE friends_a SET requests='-^B}q^A(X \\0\\0\\0176403924cdatetime\\ndatetime\\nq^BU\\n^G--\\Z^K:5^Hw.-Rq^CX \\0\\0\\0942515122h^BU\\n^G--^X^G^^$\\n^NӅRq^DX \\0\\0\\0760857294h^BU\\n^G-- ^F8+ ---Rq^EX \\0\\0\\0207000491h^BU\\n^G--^X^E^_^L^F-$-Rq^FX \\0\\0\\0281067699h^BU\\n^G--^B^O^C-^A<13>Rq^GX \\0\\0\\0941678014h^BU\\n^G--^\\^W^N^W^F-$-Rq^HX \\0\\0\\0840070155h^BU\\n^G--^\\^L\\n6^D*ʅRq X \\0\\0\\0468440035h^BU\\n^G--^V^W*^N^Bp^K-Rq\\nU 169240315h^BU\\n^G--^W^U^W1^D-m-Rq^KX \\0\\0\\0199411251h^BU\\n^G--^V^W%^^^A---Rq^LU 210660648h^BU\\n^G--^\\^W^Y-^F\\Zd-Rq\\rU 262672217h^BU\\n^G--\\Z^V2:^O^U--Rq^NX \\0\\0\\0952838443h^BU\\n^G--^\\^W!7\\r-{-Rq^OX \\0\\0\\0263642777h^BU\\n^G--^B^U/^D^G-̅Rq^PX \\0\\0\\0286685152h^BU\\n^G--^W^T3,^Ggs-Rq^QU 290976173h^BU\\n^G--^\\^V)^X^D---Rq^RX \\0\\0\\0825427842h^BU\\n^G--\\Z^V;^Q^N- -Rq^SX \\0\\0\\0399352674h^BU\\n^G--^\\^V-0^KC\\0-Rq^TX \\0\\0\\0429293778h^BU\\n^G--^Y^U ^]^C-��Rq^UX \\0\\0\\0796702973h^BU\\n^G--^Y^S^U#^F\\\\^W-Rq^Vu.',friends='-^B}q^A(X \\0\\0\\0288854421cdatetime\\ndatetime\\nq^BU\\n^G--^[^N38^L6---q^CX \\0\\0\\0307943786h^BU\\n^G--^F^V7 ^D---Rq^DX \\0\\0\\0290783072NX \\0\\0\\0498070760NX \\0\\0\\0457575155NX \\0\\0\\0304215892h^BU\\n^G--^F^W^L+^L---Rq^EX \\0\\0\\0300254457h^BU\\n^G--^F^G$)^A---Rq^FX \\0\\0\\0252042226h^BU\\n^G-- ^R8\\r ----q^GX \\0\\0\\0697110711NX \\0\\0\\0809118053h^BU\\n^G-- ^L^H^O\\0ɲ-Rq^HX \\0\\0\\0293303495h^BU\\n^G-- ^T!.^B/ʅRq X \\0\\0\\0302651538h^BU\\n^G--^G^P)^C^Fn---q\\nU 888879887h^BU\\n^G--^H^W.*^G---Rq^KX \\0\\0\\0240865621h^BU\\n^G--^G\\n2;\\n---Rq^LU 300728616h^BU\\n^G--^A^L^N8\\0\\'--Rq\\rX \\0\\0\\0856456443NX \\0\\0\\0302371154h^BU\\n^G--^A^Q^R^^\\0---Rq^NX \\0\\0\\0696458616h^BU\\n^G--^G\\n98\\n---Rq^OU 297082613NX \\0\\0\\0811281930h^BU\\n^G--\\n^Q^P^X^L^OɅRq^PU 300986758h^BU\\n^G--^F^F\\r3^G-$-Rq^QU 276325435h^BU\\n^G--^B^P^P^T^E^N8-Rq^RX \\0\\0\\0299082034h^BU\\n^G--^H^W^_^Q^D<--Rq^SX \\0\\0\\0171238051h^BU\\n^G--\\n\\r)^S^Dܢ-Rq^TX \\0\\0\\0780724792h^BU\\n^G--\\n^N+ ^F*>-Rq^UX \\0\\0\\0893552392h^BU\\n^G--\\n^N^_-^K^L--Rq^VX \\0\\0\\0590290136h^BU\\n^G-- \\r^Y0\\r --Rq^WX \\0\\0\\0302913387h^BU\\n^G--^C^K#,\\0^X9-Rq^XX \\0\\0\\0252736446NX \\0\\0\\0302360033h^BU\\n^G--^C^O^A^^^H-[-Rq^YU 276564368h^BU\\n^G--\\n\\r:+^K-q-Rq\\ZX \\0\\0\\0296693715h^BU\\n^G-- ^G^[/^A-F-Rq^[X \\0\\0\\0223225019h^BU\\n^G-- ^S^X^C\\07\\Z-Rq^\\X \\0\\0\\0232453764h^BU\\n^G--^_\\r3^V\\0---Rq^]U 297276051h^BU\\n^G--^C^K/4^K-؅Rq^^X \\0\\0\\0184978889NX \\0\\0\\0813351784h^BU\\n^G--^H^H%^X^E&^S-Rq^_X \\0\\0\\03028705")); + + Assert.assertEquals(1, provider.getTableStats().size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_statMap.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_statMap.java index c1429bd190..e3fda025e3 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_statMap.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/WallStatTest_statMap.java @@ -29,18 +29,21 @@ public class WallStatTest_statMap extends TestCase { { String sql = "select * from t where len(fname) = 1 OR 1 = 1"; Assert.assertFalse(providerA.checkValid(sql)); + providerA.addViolationEffectRowCount(10); } WallProvider providerB = new MySqlWallProvider(); { String sql = "select * from t where len(fname) = 2 OR 1 = 1"; Assert.assertFalse(providerB.checkValid(sql)); + providerB.addViolationEffectRowCount(11); } WallProvider providerC = new MySqlWallProvider(); { String sql = "select * from t where len(fname) = 2 OR 1 = 1"; Assert.assertFalse(providerC.checkValid(sql)); + providerC.addViolationEffectRowCount(12); } Map statMapA = providerA.getStatsMap(); @@ -55,11 +58,13 @@ public class WallStatTest_statMap extends TestCase { System.out.println(JSONUtils.toJSONString(statMapMerged)); Assert.assertEquals(2L, statMapMerged.get("checkCount")); + Assert.assertEquals(21L, statMapMerged.get("violationEffectRowCount")); Assert.assertEquals(2, ((Collection>) statMapMerged.get("blackList")).size()); statMapMerged = DruidStatManagerFacade.mergWallStat(statMapMerged, statMapC); System.out.println(JSONUtils.toJSONString(statMapMerged)); Assert.assertEquals(2, ((Collection>) statMapMerged.get("blackList")).size()); + Assert.assertEquals(33L, statMapMerged.get("violationEffectRowCount")); } } diff --git a/src/test/java/com/alibaba/druid/mysql/QueryTimeoutTest.java b/src/test/java/com/alibaba/druid/mysql/QueryTimeoutTest.java new file mode 100644 index 0000000000..b4e7f734e5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/mysql/QueryTimeoutTest.java @@ -0,0 +1,56 @@ +package com.alibaba.druid.mysql; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; + +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.util.JdbcUtils; + + +public class QueryTimeoutTest extends TestCase { + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:oracle:thin:@10.20.36.21:1521:OINTEST"); + dataSource.setUsername("alibaba"); + dataSource.setPassword("deYcR7facWSJtCuDpm2r"); + dataSource.setInitialSize(1); + dataSource.setMaxActive(14); + dataSource.setMinIdle(1); + dataSource.setMinEvictableIdleTimeMillis(300 * 1000); // 300 / 10 + dataSource.setTimeBetweenEvictionRunsMillis(180 * 1000); // 180 / 10 + dataSource.setTestWhileIdle(true); + dataSource.setTestOnBorrow(false); + dataSource.setValidationQuery("SELECT 1 FROM DUAL"); + dataSource.setFilters("stat"); + } + + public void test_queryTimeout() throws Exception { + { + Connection conn = dataSource.getConnection(); + + String sql = "SELECT * FROM ws_product WHERE HAVE_IMAGE = 'N' AND ROWNUM < 1000"; + PreparedStatement stmt = conn.prepareStatement(sql); + stmt.setQueryTimeout(1); + ResultSet rs = stmt.executeQuery(); + JdbcUtils.printResultSet(rs); + rs.close(); + stmt.close(); + conn.close(); + } + Connection conn = dataSource.getConnection(); + + String sql = "SELECT 'x' FROM DUAL"; + PreparedStatement stmt = conn.prepareStatement(sql); + stmt.setQueryTimeout(1); + ResultSet rs = stmt.executeQuery(); + JdbcUtils.printResultSet(rs); + rs.close(); + stmt.close(); + conn.close(); + } +} diff --git a/src/test/java/com/alibaba/druid/pool/QueryTimeoutTest.java b/src/test/java/com/alibaba/druid/pool/QueryTimeoutTest.java new file mode 100644 index 0000000000..6793105d63 --- /dev/null +++ b/src/test/java/com/alibaba/druid/pool/QueryTimeoutTest.java @@ -0,0 +1,56 @@ +package com.alibaba.druid.pool; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; + +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.util.JdbcUtils; + + +public class QueryTimeoutTest extends TestCase { + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:oracle:thin:@10.20.36.21:1521:OINTEST"); + dataSource.setUsername("alibaba"); + dataSource.setPassword("deYcR7facWSJtCuDpm2r"); + dataSource.setInitialSize(1); + dataSource.setMaxActive(14); + dataSource.setMinIdle(1); + dataSource.setMinEvictableIdleTimeMillis(300 * 1000); // 300 / 10 + dataSource.setTimeBetweenEvictionRunsMillis(180 * 1000); // 180 / 10 + dataSource.setTestWhileIdle(true); + dataSource.setTestOnBorrow(false); + dataSource.setValidationQuery("SELECT 1 FROM DUAL"); + dataSource.setFilters("stat"); + } + + public void test_queryTimeout() throws Exception { + { + Connection conn = dataSource.getConnection(); + + String sql = "SELECT * FROM ws_product WHERE HAVE_IMAGE = 'N' AND ROWNUM < 1000"; + PreparedStatement stmt = conn.prepareStatement(sql); + stmt.setQueryTimeout(1); + ResultSet rs = stmt.executeQuery(); + JdbcUtils.printResultSet(rs); + rs.close(); + stmt.close(); + conn.close(); + } + Connection conn = dataSource.getConnection(); + + String sql = "SELECT 'x' FROM DUAL"; + PreparedStatement stmt = conn.prepareStatement(sql); + stmt.setQueryTimeout(1); + ResultSet rs = stmt.executeQuery(); + JdbcUtils.printResultSet(rs); + rs.close(); + stmt.close(); + conn.close(); + } +} diff --git a/src/test/java/com/alibaba/druid/pool/oracle/QueryTimeoutTest.java b/src/test/java/com/alibaba/druid/pool/oracle/QueryTimeoutTest.java new file mode 100644 index 0000000000..39cae3deb7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/pool/oracle/QueryTimeoutTest.java @@ -0,0 +1,79 @@ +package com.alibaba.druid.pool.oracle; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.concurrent.CountDownLatch; + +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.util.JdbcUtils; + +public class QueryTimeoutTest extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mysql://10.232.64.68:3306/umiddb"); + dataSource.setUsername("umiddb"); + dataSource.setPassword("umiddb1001"); + dataSource.setInitialSize(1); + dataSource.setMaxActive(14); + dataSource.setMinIdle(1); + dataSource.setMinEvictableIdleTimeMillis(300 * 1000); // 300 / 10 + dataSource.setTimeBetweenEvictionRunsMillis(180 * 1000); // 180 / 10 + dataSource.setTestWhileIdle(true); + dataSource.setTestOnBorrow(false); + dataSource.setValidationQuery("SELECT 1"); + dataSource.setFilters("stat"); + } + + public void test_queryTimeout() throws Exception { + try { + final Connection conn = dataSource.getConnection(); + + String sql = "SELECT sleep(1)"; + final CountDownLatch latch = new CountDownLatch(1); + Thread thread = new Thread() { + public void run() { + try { + latch.countDown(); + Thread.sleep(100); + conn.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + thread.start(); + + latch.await(); + final PreparedStatement stmt = conn.prepareStatement(sql); +// stmt.setQueryTimeout(1); + + final ResultSet rs = stmt.executeQuery(); + JdbcUtils.printResultSet(rs); + rs.close(); + stmt.close(); + conn.close(); + + } catch (Exception e) { + // + e.printStackTrace(); + } + + Connection conn = dataSource.getConnection(); + + String sql = "SELECT 'x'"; + PreparedStatement stmt = conn.prepareStatement(sql); + stmt.setQueryTimeout(1); + ResultSet rs = stmt.executeQuery(); + JdbcUtils.printResultSet(rs); + rs.close(); + stmt.close(); + conn.close(); + } +}