mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve wall filter
This commit is contained in:
@@ -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()) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.<SQLStatement> emptyList());
|
||||
}
|
||||
|
||||
public WallCheckResult(List<Violation> violations, Map<String, WallSqlTableStat> tableStats,
|
||||
public WallCheckResult(WallSqlStat sqlStat, List<Violation> violations, Map<String, WallSqlTableStat> tableStats,
|
||||
Map<String, WallSqlFunctionStat> functionStats, List<SQLStatement> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +118,6 @@ public class WallConfig implements WallConfigMBean {
|
||||
this.limitZeroAllow = limitZero;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isConditionAndAlwayTrueAllow() {
|
||||
return conditionAndAlwayTrueAllow;
|
||||
}
|
||||
|
||||
@@ -20,12 +20,17 @@ import java.util.Map;
|
||||
|
||||
public class WallContext {
|
||||
|
||||
private final static ThreadLocal<WallContext> contextLocal = new ThreadLocal<WallContext>();
|
||||
private final static ThreadLocal<WallContext> contextLocal = new ThreadLocal<WallContext>();
|
||||
|
||||
private WallSqlStat sqlStat;
|
||||
private Map<String, WallSqlTableStat> tableStats;
|
||||
private Map<String, WallSqlFunctionStat> 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++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,32 +45,33 @@ public abstract class WallProvider {
|
||||
|
||||
private LRUCache<String, WallSqlStat> 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<String, WallSqlStat> 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<Boolean> privileged = new ThreadLocal<Boolean>();
|
||||
private static final ThreadLocal<Boolean> privileged = new ThreadLocal<Boolean>();
|
||||
|
||||
private final ConcurrentMap<String, WallFunctionStat> functionStats = new ConcurrentHashMap<String, WallFunctionStat>();
|
||||
private final ConcurrentMap<String, WallTableStat> tableStats = new ConcurrentHashMap<String, WallTableStat>();
|
||||
private final ConcurrentMap<String, WallFunctionStat> functionStats = new ConcurrentHashMap<String, WallFunctionStat>();
|
||||
private final ConcurrentMap<String, WallTableStat> tableStats = new ConcurrentHashMap<String, WallTableStat>();
|
||||
|
||||
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.<String> unmodifiableSet(hashSet);
|
||||
}
|
||||
|
||||
|
||||
public List<Map<String, Object>> getBlackListStat() {
|
||||
List<Map<String, Object>> map = new ArrayList<Map<String, Object>>();
|
||||
lock.readLock().lock();
|
||||
@@ -223,23 +224,24 @@ public abstract class WallProvider {
|
||||
if (blackList != null) {
|
||||
for (Map.Entry<String, WallSqlStat> entry : this.blackList.entrySet()) {
|
||||
WallSqlStat sqlStat = entry.getValue();
|
||||
|
||||
|
||||
Map<String, Object> sqlStatMap = new LinkedHashMap<String, Object>();
|
||||
sqlStatMap.put("sql", entry.getKey());
|
||||
sqlStatMap.put("executeCount", sqlStat.getExecuteCount());
|
||||
|
||||
sqlStatMap.put("effectRowCount", sqlStat.getEffectRowCount());
|
||||
|
||||
List<Violation> 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());
|
||||
|
||||
@@ -23,9 +23,13 @@ import java.util.concurrent.atomic.AtomicLongFieldUpdater;
|
||||
public class WallSqlStat {
|
||||
|
||||
private volatile long executeCount;
|
||||
private volatile long effectRowCount;
|
||||
|
||||
final static AtomicLongFieldUpdater<WallSqlStat> executeCountUpdater = AtomicLongFieldUpdater.newUpdater(WallSqlStat.class,
|
||||
"executeCount");
|
||||
final static AtomicLongFieldUpdater<WallSqlStat> executeCountUpdater = AtomicLongFieldUpdater.newUpdater(WallSqlStat.class,
|
||||
"executeCount");
|
||||
final static AtomicLongFieldUpdater<WallSqlStat> effectRowCountUpdater = AtomicLongFieldUpdater.newUpdater(WallSqlStat.class,
|
||||
"effectRowCount");
|
||||
|
||||
private final Map<String, WallSqlTableStat> tableStats;
|
||||
|
||||
private final List<Violation> 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<String, WallSqlTableStat> getTableStats() {
|
||||
return tableStats;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user