Merge remote-tracking branch 'upstream/master'

This commit is contained in:
kiki
2013-08-28 11:12:59 +08:00
20 changed files with 367 additions and 29 deletions
@@ -15,6 +15,10 @@
*/
package com.alibaba.druid.sql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLHint;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -25,10 +29,26 @@ public class SQLSelect extends SQLObjectImpl {
protected SQLSelectQuery query;
protected SQLOrderBy orderBy;
private List<SQLHint> hints;
public SQLSelect(){
}
public List<SQLHint> getHints() {
if (hints == null) {
hints = new ArrayList<SQLHint>(2);
}
return hints;
}
public int getHintsSize() {
if (hints == null) {
return 0;
}
return hints.size();
}
public SQLSelect(SQLSelectQuery query){
this.setQuery(query);
}
@@ -64,6 +84,7 @@ public class SQLSelect extends SQLObjectImpl {
if (visitor.visit(this)) {
acceptChild(visitor, this.query);
acceptChild(visitor, this.orderBy);
acceptChild(visitor, this.hints);
}
visitor.endVisit(this);
@@ -62,6 +62,10 @@ public class SQLSelectParser extends SQLParser {
if (select.getOrderBy() == null) {
select.setOrderBy(parseOrderBy());
}
if (lexer.token() == Token.HINT) {
this.exprParser.parseHints(select.getHints());
}
return select;
}
@@ -290,11 +290,6 @@ public class SQLStatementParser extends SQLParser {
continue;
}
if (lexer.token() == Token.HINT) {
lexer.nextToken();
continue;
}
if (lexer.token() == Token.COMMENT) {
statementList.add(this.parseComment());
continue;
@@ -642,6 +642,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
println();
x.getOrderBy().accept(this);
}
if (x.getHintsSize() > 0) {
printAndAccept(x.getHints(), "");
}
return false;
}
@@ -722,6 +722,24 @@ public abstract class WallProvider {
}
private WallCheckResult checkWhiteAndBlackList(String sql) {
// check black list
if (blackListEnable) {
WallSqlStat sqlStat = getBlackSql(sql);
if (sqlStat != null) {
blackListHitCount.incrementAndGet();
violationCount.incrementAndGet();
if (sqlStat.isSyntaxError()) {
syntaxErrrorCount.incrementAndGet();
}
sqlStat.incrementAndGetExecuteCount();
recordStats(sqlStat.getTableStats(), sqlStat.getFunctionStats());
return new WallCheckResult(sqlStat);
}
}
if (whiteListEnable) {
WallSqlStat sqlStat = getWhiteSql(sql);
if (sqlStat != null) {
@@ -740,23 +758,6 @@ public abstract class WallProvider {
return new WallCheckResult(sqlStat);
}
}
// check black list
if (blackListEnable) {
WallSqlStat sqlStat = getBlackSql(sql);
if (sqlStat != null) {
blackListHitCount.incrementAndGet();
violationCount.incrementAndGet();
if (sqlStat.isSyntaxError()) {
syntaxErrrorCount.incrementAndGet();
}
sqlStat.incrementAndGetExecuteCount();
recordStats(sqlStat.getTableStats(), sqlStat.getFunctionStats());
return new WallCheckResult(sqlStat);
}
}
return null;
}
@@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
@@ -78,7 +79,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
this.config = provider.getConfig();
this.provider = provider;
}
@Override
public String getDbType() {
return JdbcConstants.MYSQL;
@@ -433,6 +434,53 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
return false;
}
@Override
public boolean visit(SQLCommentHint x) {
String text = x.getText();
text = text.trim();
if (text.startsWith("!")) {
text = text.substring(1);
}
if (text.length() == 0) {
return true;
}
if (Character.isDigit(text.charAt(0))) {
addViolation(new IllegalSQLObjectViolation(ErrorCode.EVIL_HINTS, "evil hints", SQLUtils.toMySqlString(x)));
}
text = text.toLowerCase();
if (text.indexOf(';') != -1 //
|| text.indexOf("or") != -1 //
|| text.indexOf("and") != -1 //
|| text.indexOf("union") != -1 //
|| text.indexOf("select") != -1 //
|| text.indexOf("delete") != -1 //
|| text.indexOf("insert") != -1 //
|| text.indexOf("update") != -1 //
|| text.indexOf("create") != -1 //
|| text.indexOf("drop") != -1 //
|| text.indexOf("alter") != -1 //
|| text.indexOf("truncate") != -1 //
|| text.indexOf("information_schema") != -1 //
|| text.indexOf("mysql") != -1 //
|| text.indexOf("performance_schema") != -1 //
|| text.indexOf("sleep") != -1 //
|| text.indexOf("benchmark") != -1 //
|| text.indexOf("load_file") != -1 //
) {
addViolation(new IllegalSQLObjectViolation(ErrorCode.EVIL_HINTS, "evil hints", SQLUtils.toMySqlString(x)));
}
return true;
}
@Override
public boolean visit(MySqlShowCreateTableStatement x) {
String tableName = ((SQLName) x.getName()).getSimleName();
@@ -52,6 +52,7 @@ import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
@@ -162,11 +163,19 @@ public class WallVisitorUtils {
}
public static void check(WallVisitor visitor, SQLSelectItem x) {
SQLExpr expr = x.getExpr();
if (expr instanceof SQLVariantRefExpr) {
if ("@".equals(((SQLVariantRefExpr) expr).getName())) {
addViolation(visitor, ErrorCode.EVIL_NAME, "@ not allow", x);
}
}
if (visitor.getConfig().isSelectAllColumnAllow()) {
return;
}
if (x.getExpr() instanceof SQLAllColumnExpr //
if (expr instanceof SQLAllColumnExpr //
&& x.getParent() instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) x.getParent();
SQLTableSource from = queryBlock.getFrom();
@@ -1015,7 +1024,7 @@ public class WallVisitorUtils {
if (visitor != null) {
dbType = visitor.getDbType();
}
if (x instanceof SQLMethodInvokeExpr //
|| x instanceof SQLBetweenExpr //
|| x instanceof SQLInListExpr //
@@ -1034,7 +1043,7 @@ public class WallVisitorUtils {
addViolation(visitor, ErrorCode.CONST_CASE_CONDITION, "const case condition", caseExpr);
}
}
return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false);
}
@@ -64,6 +64,8 @@ public interface ErrorCode {
public final static int DOUBLE_CONST_CONDITION = 2107;
public final static int SAME_CONST_LIKE = 2108;
public final static int CONST_CASE_CONDITION = 2109;
public final static int EVIL_HINTS = 2110;
public final static int EVIL_NAME = 2111;
public final static int NOT_PARAMETERIZED = 2200;
public final static int MULTI_TENANT = 2201;
@@ -23,10 +23,10 @@ public class IllegalSQLObjectViolation implements Violation {
private final String sqlPart;
private final int errorCode;
public IllegalSQLObjectViolation(int errorCode, String message, String condition){
public IllegalSQLObjectViolation(int errorCode, String message, String sqlPart){
this.errorCode = errorCode;
this.message = message;
this.sqlPart = condition;
this.sqlPart = sqlPart;
}
public String getSqlPart() {