mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user