modify sql wall rule

This commit is contained in:
kiki
2013-06-06 12:04:39 +08:00
parent 5f16d1ac07
commit 5399447ec3
24 changed files with 646 additions and 142 deletions
@@ -34,18 +34,14 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable {
}
public SQLBetweenExpr(SQLExpr testExpr, SQLExpr beginExpr, SQLExpr endExpr){
this.testExpr = testExpr;
this.beginExpr = beginExpr;
this.endExpr = endExpr;
setTestExpr(testExpr);
setBeginExpr(beginExpr);
setEndExpr(endExpr);
}
public SQLBetweenExpr(SQLExpr testExpr, boolean not, SQLExpr beginExpr, SQLExpr endExpr){
this.testExpr = testExpr;
this(testExpr, beginExpr, endExpr);
this.not = not;
this.beginExpr = beginExpr;
this.endExpr = endExpr;
}
public void output(StringBuffer buf) {
@@ -74,6 +70,9 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable {
}
public void setTestExpr(SQLExpr testExpr) {
if (testExpr != null) {
testExpr.setParent(this);
}
this.testExpr = testExpr;
}
@@ -90,6 +89,9 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable {
}
public void setBeginExpr(SQLExpr beginExpr) {
if (beginExpr != null) {
beginExpr.setParent(this);
}
this.beginExpr = beginExpr;
}
@@ -98,6 +100,9 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable {
}
public void setEndExpr(SQLExpr endExpr) {
if (endExpr != null) {
endExpr.setParent(this);
}
this.endExpr = endExpr;
}
@@ -31,8 +31,7 @@ public class SQLQueryExpr extends SQLExprImpl implements Serializable {
}
public SQLQueryExpr(SQLSelect select){
this.subQuery = select;
setSubQuery(select);
}
public SQLSelect getSubQuery() {
@@ -40,6 +39,9 @@ public class SQLQueryExpr extends SQLExprImpl implements Serializable {
}
public void setSubQuery(SQLSelect subQuery) {
if (subQuery != null) {
subQuery.setParent(this);
}
this.subQuery = subQuery;
}
@@ -163,11 +163,16 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
@Override
public boolean visit(SQLInsertStatement x) {
WallVisitorUtils.initWallTopStatementContext();
WallVisitorUtils.checkInsert(this, x);
return true;
}
@Override
public void endVisit(SQLInsertStatement x) {
WallVisitorUtils.clearWallTopStatementContext();
}
@Override
public boolean visit(SQLSelectStatement x) {
if (!config.isSelelctAllow()) {
@@ -124,6 +124,11 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements
@Override
public boolean visit(SQLMethodInvokeExpr x) {
if (x.getParent() instanceof SQLExprTableSource) {
WallVisitorUtils.checkFunctionInTableSource(this, x);
}
WallVisitorUtils.checkFunction(this, x);
return true;
@@ -188,10 +193,16 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements
@Override
public boolean visit(SQLInsertStatement x) {
WallVisitorUtils.initWallTopStatementContext();
WallVisitorUtils.checkInsert(this, x);
return true;
}
@Override
public void endVisit(SQLInsertStatement x) {
WallVisitorUtils.clearWallTopStatementContext();
}
@Override
public boolean visit(SQLDeleteStatement x) {
WallVisitorUtils.checkDelete(this, x);
@@ -37,6 +37,7 @@ import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLInSubQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
@@ -703,6 +704,17 @@ public class WallVisitorUtils {
return false;
}
private static boolean hasWhere(SQLSelectQuery selectQuery) {
if (selectQuery instanceof SQLSelectQueryBlock) {
return ((SQLSelectQueryBlock) selectQuery).getWhere() != null;
} else if (selectQuery instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) selectQuery;
return hasWhere(union.getLeft()) || hasWhere(union.getRight());
}
return false;
}
public static boolean isWhereOrHaving(SQLObject x) {
if (x == null) {
return false;
@@ -715,12 +727,17 @@ public class WallVisitorUtils {
return false;
}
if (parent instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) parent;
if (union.getRight() == x && hasWhere(union.getLeft())) {
return true;
}
}
if (parent instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock query = (SQLSelectQueryBlock) parent;
if (query.getWhere() == x) {
return true;
} else {
return false;
}
}
@@ -1037,6 +1054,25 @@ public class WallVisitorUtils {
return false;
}
public static void checkFunctionInTableSource(WallVisitor visitor, SQLMethodInvokeExpr x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return;
}
checkSchema(visitor, x.getOwner());
String methodName = x.getMethodName();
if (!visitor.getProvider().checkDenyTable(methodName)) {
if (isTopUpdateStatement(x) || isFirstSelectTableSource(x)) {
if (topStatementContext != null) {
topStatementContext.setFromSysSchema(Boolean.TRUE);
clearViolation(visitor);
}
}
}
}
public static void checkFunction(WallVisitor visitor, SQLMethodInvokeExpr x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
@@ -1113,6 +1149,14 @@ public class WallVisitorUtils {
}
public static boolean isTopNoneFromSelect(WallVisitor visitor, SQLObject x) {
for (;;) {
if (x.getParent() instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (!(x.getParent() instanceof SQLSelectItem)) {
return false;
}
@@ -1152,10 +1196,8 @@ public class WallVisitorUtils {
String owner = ((SQLName) x).getSimleName();
owner = WallVisitorUtils.form(owner);
if (!visitor.getProvider().checkDenySchema(owner)) {
boolean topStatement = isTopSelectStatement(x) || isTopUpdateStatement(x);
boolean isWhereOrHaving = isWhereOrHaving(x);
if (!topStatement && isWhereOrHaving) {
if (!isTopUpdateStatement(x) && !isFirstSelectTableSource(x)) {
SQLObject parent = x.getParent();
while (parent != null && !(parent instanceof SQLStatement)) {
parent = parent.getParent();
@@ -1194,6 +1236,7 @@ public class WallVisitorUtils {
} else {
if (topStatementContext != null) {
topStatementContext.setFromSysSchema(Boolean.TRUE);
clearViolation(visitor);
}
}
return true;
@@ -1213,55 +1256,127 @@ public class WallVisitorUtils {
return true;
}
private static boolean isTopSelectStatement(SQLObject x) {
private static boolean isFirstSelectTableSource(SQLObject x) {
boolean topSelectStatement = false;
for (;;) {
if (x instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (!(x instanceof SQLExprTableSource)) {
return false;
}
SQLSelectQueryBlock queryBlock = null;
SQLObject parent = x.getParent();
while (parent != null) {
if (parent instanceof SQLSelectStatement || parent instanceof MySqlShowStatement) {
parent = parent.getParent();
if (parent == null) {
topSelectStatement = true;
if (parent instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) parent;
if (join.getRight() == x && hasTableSource(join.getLeft())) {
return false;
}
break;
}
if (parent instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) parent;
if (union.getRight() == x) {
break;
}
if (parent instanceof SQLSelectQueryBlock) {
queryBlock = (SQLSelectQueryBlock) parent;
break;
}
x = parent;
parent = x.getParent();
}
return topSelectStatement;
if (queryBlock == null) {
return false;
}
boolean isQueryExpr = false;
do {
x = parent;
parent = parent.getParent();
if (parent instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) parent;
if (union.getRight() == x && hasTableSource(union.getLeft())) {
return false;
}
} else if (parent instanceof SQLQueryExpr || parent instanceof SQLInSubQueryExpr) {
isQueryExpr = true;
} else if (isQueryExpr && parent instanceof SQLSelectQueryBlock) {
if (hasTableSource((SQLSelectQueryBlock) parent)) {
return false;
}
}
} while (parent != null);
return true;
}
private static boolean hasTableSource(SQLSelectQuery x) {
if (x instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) x;
return hasTableSource(union.getLeft()) || hasTableSource(union.getRight());
} else if (x instanceof SQLSelectQueryBlock) {
return hasTableSource(((SQLSelectQueryBlock) x).getFrom());
}
return false;
}
private static boolean hasTableSource(SQLTableSource x) {
if (x == null) {
return false;
}
if (x instanceof SQLExprTableSource) {
SQLExpr fromExpr = ((SQLExprTableSource) x).getExpr();
if (fromExpr instanceof SQLName) {
String name = fromExpr.toString();
name = form(name);
if (name.equalsIgnoreCase("DUAL")) {
return false;
}
}
return true;
} else if (x instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) x;
return hasTableSource(join.getLeft()) || hasTableSource(join.getRight());
} else if (x instanceof SQLSubqueryTableSource) {
return hasTableSource(((SQLSubqueryTableSource) x).getSelect().getQuery());
}
return false;
}
private static boolean isTopUpdateStatement(SQLObject x) {
boolean topUpdateStatement = false;
while (x != null) {
for (;;) {
if (x instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (x instanceof SQLExprTableSource) {
x = x.getParent();
if (x instanceof SQLUpdateStatement) {
x = x.getParent();
if (x == null) {
topUpdateStatement = true;
return true;
}
break;
}
x = x.getParent();
}
return topUpdateStatement;
return false;
}
public static boolean check(WallVisitor visitor, SQLExprTableSource x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return true;
}
SQLExpr expr = x.getExpr();
if (expr instanceof SQLPropertyExpr) {
@@ -1305,18 +1420,21 @@ public class WallVisitorUtils {
}
}
if (visitor.isDenyTable(tableName)) {
boolean topStatement = isTopSelectStatement(x) || isTopUpdateStatement(x);
boolean isWhereOrHaving = isWhereOrHaving(x);
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return true;
}
if (topStatement || !isWhereOrHaving) {
if (visitor.isDenyTable(tableName)) {
if (isTopUpdateStatement(x) || isFirstSelectTableSource(x)) {
if (topStatementContext != null) {
topStatementContext.setFromSysTable(Boolean.TRUE);
clearViolation(visitor);
}
return false;
}
boolean isTopNoneFrom = isTopSelectStatement(x);
boolean isTopNoneFrom = isTopNoneFromSelect(visitor, x);
if (isTopNoneFrom) {
return false;
}
@@ -1333,6 +1451,10 @@ public class WallVisitorUtils {
visitor.addViolation(new IllegalSQLObjectViolation(errorCode, message, visitor.toSQL(x)));
}
private static void clearViolation(WallVisitor visitor) {
visitor.getViolations().clear();
}
public static void checkUnion(WallVisitor visitor, SQLUnionQuery x) {
if (x.getOperator() == SQLUnionOperator.MINUS && !visitor.getConfig().isMinusAllow()) {
addViolation(visitor, ErrorCode.INTERSET_NOT_ALLOW, "minus not allow", x);