From 4d85e9630166ac3e5551fea387181564c584eacf Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 27 Mar 2013 18:21:08 +0800 Subject: [PATCH] improve sql parser --- .../sql/ast/statement/SQLJoinTableSource.java | 34 ++++++---- .../dialect/mysql/parser/MySqlExprParser.java | 64 +++++++++++-------- .../mysql/parser/MySqlSelectParser.java | 22 ++++--- .../oracle/ast/stmt/OracleSelectJoin.java | 8 --- .../alibaba/druid/sql/parser/Keywords.java | 1 - .../alibaba/druid/sql/parser/SQLParser.java | 48 +++++++------- .../druid/sql/parser/SQLSelectParser.java | 5 ++ .../sql/visitor/SQLASTOutputVisitor.java | 6 ++ .../com/alibaba/druid/wall/WallConfig.java | 20 +++++- .../com/alibaba/druid/wall/WallProvider.java | 24 +++---- .../druid/wall/spi/MySqlWallVisitor.java | 14 +++- .../druid/wall/mysql/deny-function.txt | 3 +- .../bvt/filter/wall/MySqlWallTest10.java | 37 +++++++++++ .../bvt/filter/wall/MySqlWallTest11.java | 42 ++++++++++++ .../bvt/filter/wall/MySqlWallTest12.java | 39 +++++++++++ .../bvt/filter/wall/MySqlWallTest13.java | 40 ++++++++++++ .../bvt/filter/wall/MySqlWallTest14.java | 39 +++++++++++ .../bvt/filter/wall/MySqlWallTest15.java | 46 +++++++++++++ .../bvt/filter/wall/MySqlWallTest16.java | 37 +++++++++++ .../bvt/filter/wall/MySqlWallTest17.java | 37 +++++++++++ .../bvt/filter/wall/MySqlWallTest18.java | 37 +++++++++++ .../bvt/filter/wall/MySqlWallTest19.java | 37 +++++++++++ .../druid/bvt/filter/wall/MySqlWallTest9.java | 39 +++++++++++ .../druid/bvt/filter/wall/PGWallTest.java | 15 +++++ 24 files changed, 597 insertions(+), 97 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest10.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest11.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest12.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest13.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest14.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest15.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest16.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest17.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest18.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest19.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest9.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/PGWallTest.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java index 0668977fcf..5c3d822f18 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLJoinTableSource.java @@ -15,17 +15,21 @@ */ package com.alibaba.druid.sql.ast.statement; +import java.util.ArrayList; +import java.util.List; + import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLJoinTableSource extends SQLTableSourceImpl { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - protected SQLTableSource left; - protected JoinType joinType; - protected SQLTableSource right; - protected SQLExpr condition; + protected SQLTableSource left; + protected JoinType joinType; + protected SQLTableSource right; + protected SQLExpr condition; + protected final List using = new ArrayList(); public SQLJoinTableSource(String alias){ super(alias); @@ -40,6 +44,7 @@ public class SQLJoinTableSource extends SQLTableSourceImpl { acceptChild(visitor, this.left); acceptChild(visitor, this.right); acceptChild(visitor, this.condition); + acceptChild(visitor, this.using); } visitor.endVisit(this); @@ -77,6 +82,10 @@ public class SQLJoinTableSource extends SQLTableSourceImpl { this.condition = condition; } + public List getUsing() { + return this.using; + } + public void output(StringBuffer buf) { this.left.output(buf); buf.append(' '); @@ -91,15 +100,13 @@ public class SQLJoinTableSource extends SQLTableSourceImpl { } public static enum JoinType { - COMMA(","), // + COMMA(","), // JOIN("JOIN"), // - INNER_JOIN("INNER JOIN"), // - CROSS_JOIN("CROSS JOIN"), // - NATURAL_JOIN("NATURAL JOIN"), // - NATURAL_INNER_JOIN("NATURAL INNER JOIN"), // - LEFT_OUTER_JOIN("LEFT JOIN"), - RIGHT_OUTER_JOIN("RIGHT JOIN"), - FULL_OUTER_JOIN("FULL JOIN"), + INNER_JOIN("INNER JOIN"), // + CROSS_JOIN("CROSS JOIN"), // + NATURAL_JOIN("NATURAL JOIN"), // + NATURAL_INNER_JOIN("NATURAL INNER JOIN"), // + LEFT_OUTER_JOIN("LEFT JOIN"), RIGHT_OUTER_JOIN("RIGHT JOIN"), FULL_OUTER_JOIN("FULL JOIN"), STRAIGHT_JOIN("STRAIGHT_JOIN"); public final String name; @@ -107,6 +114,7 @@ public class SQLJoinTableSource extends SQLTableSourceImpl { JoinType(String name){ this.name = name; } + public static String toString(JoinType joinType) { return joinType.name; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java index 45f881d7ed..6605f87cf4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java @@ -57,7 +57,7 @@ public class MySqlExprParser extends SQLExprParser { super(lexer); } - public MySqlExprParser(String sql) { + public MySqlExprParser(String sql){ this(new MySqlLexer(sql)); this.lexer.nextToken(); } @@ -71,7 +71,7 @@ public class MySqlExprParser extends SQLExprParser { return new SQLBinaryOpExpr(expr, SQLBinaryOperator.RegExp, rightExp); } - + if (identifierEquals("RLIKE")) { lexer.nextToken(); SQLExpr rightExp = equality(); @@ -106,7 +106,7 @@ public class MySqlExprParser extends SQLExprParser { return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotRegExp, rightExp); } - + if (identifierEquals("RLIKE")) { lexer.nextToken(); SQLExpr rightExp = primary(); @@ -121,14 +121,14 @@ public class MySqlExprParser extends SQLExprParser { public SQLExpr primary() { final Token tok = lexer.token(); - + if (identifierEquals("outfile")) { lexer.nextToken(); SQLExpr file = primary(); SQLExpr expr = new MySqlOutFileExpr(file); - + return primaryRest(expr); - + } switch (tok) { @@ -155,7 +155,7 @@ public class MySqlExprParser extends SQLExprParser { } else if (varRefExpr.getName().equals("@@") && lexer.token() == Token.LITERAL_CHARS) { varRefExpr.setName("@@'" + lexer.stringVal() + "'"); lexer.nextToken(); - } + } return primaryRest(varRefExpr); case VALUES: lexer.nextToken(); @@ -400,6 +400,10 @@ public class MySqlExprParser extends SQLExprParser { } else { matchAgainstExpr.setSearchModifier(SearchModifier.IN_NATURAL_LANGUAGE_MODE); } + } else if (identifierEquals("BOOLEAN")) { + lexer.nextToken(); + acceptIdentifier("MODE"); + matchAgainstExpr.setSearchModifier(SearchModifier.IN_BOOLEAN_MODE); } else { throw new ParserException("TODO"); } @@ -437,16 +441,16 @@ public class MySqlExprParser extends SQLExprParser { return primaryRest(expr); } } - + if (lexer.token() == Token.VARIANT && "@".equals(lexer.stringVal())) { lexer.nextToken(); MySqlUserName userName = new MySqlUserName(); if (expr instanceof SQLCharExpr) { - userName.setUserName(((SQLCharExpr)expr).toString()); + userName.setUserName(((SQLCharExpr) expr).toString()); } else { - userName.setUserName(((SQLIdentifierExpr)expr).getName()); + userName.setUserName(((SQLIdentifierExpr) expr).getName()); } - + if (lexer.token() == Token.LITERAL_CHARS) { userName.setHost("'" + lexer.stringVal() + "'"); } else { @@ -494,7 +498,7 @@ public class MySqlExprParser extends SQLExprParser { return intervalExpr; } } - + public SQLColumnDefinition parseColumn() { MySqlSQLColumnDefinition column = new MySqlSQLColumnDefinition(); column.setName(name()); @@ -511,7 +515,7 @@ public class MySqlExprParser extends SQLExprParser { } return parseColumnRest(column); } - + if (identifierEquals("PARTITION")) { throw new ParserException("syntax error " + lexer.token() + " " + lexer.stringVal()); } @@ -519,7 +523,7 @@ public class MySqlExprParser extends SQLExprParser { return column; } - + public SQLExpr orRest(SQLExpr expr) { for (;;) { @@ -540,23 +544,23 @@ public class MySqlExprParser extends SQLExprParser { return expr; } - + public SQLAssignItem parseAssignItem() { SQLAssignItem item = new SQLAssignItem(); - + SQLExpr var = primary(); - + if (var instanceof SQLIdentifierExpr) { String ident = ((SQLIdentifierExpr) var).getName(); - + if ("GLOBAL".equalsIgnoreCase(ident)) { ident = lexer.stringVal(); lexer.nextToken(); var = new SQLVariantRefExpr(ident, true); } else if ("SESSION".equalsIgnoreCase(ident)) { - ident = lexer.stringVal(); - lexer.nextToken(); - var = new SQLVariantRefExpr(ident, false); + ident = lexer.stringVal(); + lexer.nextToken(); + var = new SQLVariantRefExpr(ident, false); } else { var = new SQLVariantRefExpr(ident); } @@ -567,17 +571,21 @@ public class MySqlExprParser extends SQLExprParser { } else { accept(Token.EQ); } - item.setValue(expr()); - + if (lexer.token() == Token.BINARY) { + lexer.nextToken(); + item.setValue(new SQLIdentifierExpr("BINARY")); + } else { + item.setValue(expr()); + } return item; } - + public SQLName nameRest(SQLName name) { if (lexer.token() == Token.VARIANT && "@".equals(lexer.stringVal())) { lexer.nextToken(); MySqlUserName userName = new MySqlUserName(); - userName.setUserName(((SQLIdentifierExpr)name).getName()); - + userName.setUserName(((SQLIdentifierExpr) name).getName()); + if (lexer.token() == Token.LITERAL_CHARS) { userName.setHost("'" + lexer.stringVal() + "'"); } else { @@ -588,7 +596,7 @@ public class MySqlExprParser extends SQLExprParser { } return super.nameRest(name); } - + public Limit parseLimit() { if (lexer.token() == Token.LIMIT) { lexer.nextToken(); @@ -639,7 +647,7 @@ public class MySqlExprParser extends SQLExprParser { return primaryKey; } - + public MySqlUnique parseUnique() { accept(Token.UNIQUE); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java index bb39281bd1..321d07d27a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java @@ -17,6 +17,7 @@ package com.alibaba.druid.sql.dialect.mysql.parser; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLSetQuantifier; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; @@ -44,7 +45,7 @@ public class MySqlSelectParser extends SQLSelectParser { super(exprParser); } - public MySqlSelectParser(String sql) { + public MySqlSelectParser(String sql){ this(new MySqlExprParser(sql)); } @@ -63,7 +64,7 @@ public class MySqlSelectParser extends SQLSelectParser { if (lexer.token() == Token.SELECT) { lexer.nextToken(); - + if (lexer.token() == Token.HINT) { this.exprParser.parseHints(queryBlock.getHints()); } @@ -273,7 +274,7 @@ public class MySqlSelectParser extends SQLSelectParser { parseIndexHint(hint); tableSource.getHints().add(hint); } - + if (identifierEquals("FORCE")) { lexer.nextToken(); MySqlForceIndexHint hint = new MySqlForceIndexHint(); @@ -290,10 +291,10 @@ public class MySqlSelectParser extends SQLSelectParser { } else { accept(Token.KEY); } - + if (lexer.token() == Token.FOR) { lexer.nextToken(); - + if (lexer.token() == Token.JOIN) { lexer.nextToken(); hint.setOption(MySqlIndexHint.Option.JOIN); @@ -307,9 +308,14 @@ public class MySqlSelectParser extends SQLSelectParser { hint.setOption(MySqlIndexHint.Option.GROUP_BY); } } - + accept(Token.LPAREN); - this.exprParser.names(hint.getIndexList()); + if (lexer.token() == Token.PRIMARY) { + lexer.nextToken(); + hint.getIndexList().add(new SQLIdentifierExpr("PRIMARY")); + } else { + this.exprParser.names(hint.getIndexList()); + } accept(Token.RPAREN); } @@ -326,6 +332,6 @@ public class MySqlSelectParser extends SQLSelectParser { } public Limit parseLimit() { - return ((MySqlExprParser)this.exprParser) .parseLimit(); + return ((MySqlExprParser) this.exprParser).parseLimit(); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java index b9bb88557b..3397593543 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleSelectJoin.java @@ -15,9 +15,6 @@ */ package com.alibaba.druid.sql.dialect.oracle.ast.stmt; -import java.util.ArrayList; -import java.util.List; - import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause; @@ -28,7 +25,6 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect private static final long serialVersionUID = 1L; - private final List using = new ArrayList(); protected OracleSelectPivotBase pivot; protected FlashbackQueryClause flashback; @@ -73,10 +69,6 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect visitor.endVisit(this); } - public List getUsing() { - return this.using; - } - public void output(StringBuffer buf) { this.left.output(buf); buf.append(JoinType.toString(this.joinType)); diff --git a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java index ab8d2a0f1e..6789d8d8ab 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java @@ -81,7 +81,6 @@ public class Keywords { map.put("LIKE", Token.LIKE); map.put("LOCK", Token.LOCK); map.put("MINUS", Token.MINUS); - map.put("NEW", Token.NEW); map.put("NOT", Token.NOT); map.put("NULL", Token.NULL); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java index 79e68ca6cd..3f7e53eace 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java @@ -45,7 +45,7 @@ public class SQLParser { } } - protected String as() { + protected String as() { String alias = null; if (lexer.token() == Token.AS) { @@ -54,36 +54,38 @@ public class SQLParser { if (lexer.token() == Token.LITERAL_ALIAS) { alias = '"' + lexer.stringVal() + '"'; lexer.nextToken(); - return alias; - } - - if (lexer.token() == Token.IDENTIFIER) { + } else if (lexer.token() == Token.IDENTIFIER) { alias = lexer.stringVal(); lexer.nextToken(); - return alias; - } - - if (lexer.token() == Token.LITERAL_CHARS) { + } else if (lexer.token() == Token.LITERAL_CHARS) { alias = "'" + lexer.stringVal() + "'"; lexer.nextToken(); - return alias; + } else { + switch (lexer.token()) { + case KEY: + case INDEX: + case CASE: + alias = lexer.token().name(); + lexer.nextToken(); + return alias; + case QUES: + alias = "?"; + lexer.nextToken(); + default: + break; + } } - if (lexer.token() == Token.KEY || lexer.token() == Token.CASE) { - alias = lexer.token.name(); - lexer.nextToken(); - return alias; - } - - switch (lexer.token()) { - case KEY: - alias = lexer.token().name(); + if (alias != null) { + while (lexer.token() == Token.DOT) { lexer.nextToken(); - return alias; - default: - break; + alias += ('.' + lexer.token().name()); + lexer.nextToken(); + } + + return alias; } - + if (lexer.token() == Token.LPAREN) { return null; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index 23bfdf674d..d0cff2ee71 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -386,6 +386,11 @@ public class SQLSelectParser extends SQLParser { if (lexer.token() == Token.ON) { lexer.nextToken(); join.setCondition(expr()); + } else if (identifierEquals("USING")) { + lexer.nextToken(); + accept(Token.LPAREN); + this.exprParser.exprList(join.getUsing()); + accept(Token.RPAREN); } return parseTableSourceRest(join); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 8ad4d3c790..a7b945d05b 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1074,6 +1074,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { x.getCondition().accept(this); decrementIndent(); } + + if (x.getUsing().size() > 0) { + print(" USING ("); + printAndAccept(x.getUsing(), ", "); + print(")"); + } decrementIndent(); diff --git a/src/main/java/com/alibaba/druid/wall/WallConfig.java b/src/main/java/com/alibaba/druid/wall/WallConfig.java index d40678c059..56abcf3192 100644 --- a/src/main/java/com/alibaba/druid/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/wall/WallConfig.java @@ -46,6 +46,8 @@ public class WallConfig implements WallConfigMBean { private boolean mergeAllow = true; private boolean minusAllow = false; private boolean intersectAllow = false; + private boolean replaceAllow = true; + private boolean setAllow = true; private boolean multiStatementAllow = false; @@ -90,7 +92,7 @@ public class WallConfig implements WallConfigMBean { private boolean metadataAllow = true; private boolean conditionOpXorAllow = false; - private boolean conditionOpBitwseAllow = false; + private boolean conditionOpBitwseAllow = true; public WallConfig(){ @@ -338,6 +340,22 @@ public class WallConfig implements WallConfigMBean { this.insertAllow = insertAllow; } + public boolean isReplaceAllow() { + return replaceAllow; + } + + public void setReplaceAllow(boolean replaceAllow) { + this.replaceAllow = replaceAllow; + } + + public boolean isSetAllow() { + return setAllow; + } + + public void setSetAllow(boolean value) { + this.setAllow = value; + } + public boolean isMergeAllow() { return mergeAllow; } diff --git a/src/main/java/com/alibaba/druid/wall/WallProvider.java b/src/main/java/com/alibaba/druid/wall/WallProvider.java index 613ce465f0..ac36421c3f 100644 --- a/src/main/java/com/alibaba/druid/wall/WallProvider.java +++ b/src/main/java/com/alibaba/druid/wall/WallProvider.java @@ -263,15 +263,20 @@ public abstract class WallProvider { sqlStat.incrementAndGetExecuteCount(); return result; } - - SQLStatementParser parser = createParser(sql); - - if (!config.isCommentAllow()) { - parser.getLexer().setAllowComment(false); // deny comment - } - + try { + SQLStatementParser parser = createParser(sql); + + if (!config.isCommentAllow()) { + parser.getLexer().setAllowComment(false); // deny comment + } + parser.parseStatementList(result.getStatementList()); + + if (parser.getLexer().token() != Token.EOF) { + result.getViolations().add(new IllegalSQLObjectViolation(sql)); + return result; + } } catch (NotAllowCommentException e) { result.getViolations().add(new SyntaxErrorViolation(e, sql)); incrementCommentDeniedCount(); @@ -286,11 +291,6 @@ public abstract class WallProvider { return result; } - if (parser.getLexer().token() != Token.EOF) { - result.getViolations().add(new IllegalSQLObjectViolation(sql)); - return result; - } - if (result.getStatementList().size() == 0) { return result; } 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 201fe6957c..29f48e9667 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -36,6 +36,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.statement.SQLSetStatement; import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; @@ -43,9 +44,12 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr; 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.MySqlInsertStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; @@ -223,7 +227,7 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi return true; } - + @Override public boolean visit(MySqlUnionQuery x) { WallVisitorUtils.checkUnion(this, x); @@ -269,10 +273,16 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi allow = config.isTruncateAllow(); } else if (x instanceof MySqlDescribeStatement) { allow = config.isDescribeAllow(); + } else if (x instanceof MySqlReplaceStatement) { + allow = config.isReplaceAllow(); + } else if (x instanceof MySqlSetCharSetStatement // + || x instanceof MySqlSetNamesStatement // + || x instanceof SQLSetStatement) { + allow = config.isSetAllow(); } if (!allow) { - violations.add(new IllegalSQLObjectViolation(toSQL(x))); + violations.add(new IllegalSQLObjectViolation(x.getClass() + " not allow, " + toSQL(x))); } } diff --git a/src/main/resources/META-INF/druid/wall/mysql/deny-function.txt b/src/main/resources/META-INF/druid/wall/mysql/deny-function.txt index a3752fb9f2..ad53b20f9d 100644 --- a/src/main/resources/META-INF/druid/wall/mysql/deny-function.txt +++ b/src/main/resources/META-INF/druid/wall/mysql/deny-function.txt @@ -7,4 +7,5 @@ system_user session_user benchmark connection_id -current_user \ No newline at end of file +current_user +sleep \ No newline at end of file diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest10.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest10.java new file mode 100644 index 0000000000..fbba42af75 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest10.java @@ -0,0 +1,37 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest10 extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT t.*,a.param_id FROM lhwtag AS t RIGHT JOIN lhwtag_relation AS a USING(`tag_id`) WHERE a.`type_id`=1 AND a.`param_id` IN ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ORDER BY t.`content_count`")); // 前置永真 + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest11.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest11.java new file mode 100644 index 0000000000..02342b59b8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest11.java @@ -0,0 +1,42 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest11 extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT *, MATCH(question_content_fulltext) " + // + "AGAINST('2015431867 2636826089 3807520117 2796321160 2615920174' IN BOOLEAN MODE) AS score " + // + "FROM aws_question " + // + "WHERE MATCH(question_content_fulltext) " + // + " AGAINST('2015431867 2636826089 3807520117 2796321160 2615920174' IN BOOLEAN MODE) " + // + "ORDER BY score DESC, agree_count DESC LIMIT 10")); // + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest12.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest12.java new file mode 100644 index 0000000000..3c1b947528 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest12.java @@ -0,0 +1,39 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest12 extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT a.* FROM lhwbbs_threads a " + // + "WHERE 1 AND a.disabled=0 AND a.ifupload&1=1 " + // + "ORDER BY a.created_time DESC LIMIT 0,100")); // + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest13.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest13.java new file mode 100644 index 0000000000..0fc4430cb6 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest13.java @@ -0,0 +1,40 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest13 extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT index_privacy AS index,msgboard_privacy AS messageboard," + // + "photos_privacy AS photos,diary_privacy AS diary," + // + "owrite_privacy AS weibo " + // + "FROM pw_ouserdata WHERE uid= ?")); // + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest14.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest14.java new file mode 100644 index 0000000000..cf83013ea1 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest14.java @@ -0,0 +1,39 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest14 extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT index_privacy AS index,info_privacy AS ?,msgboard_privacy AS messageboard,photos_privacy AS photos," + // + "diary_privacy AS diary,owrite_privacy AS weibo " + // + "FROM pw_ouserdata WHERE uid= ?")); // + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest15.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest15.java new file mode 100644 index 0000000000..1583372b3e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest15.java @@ -0,0 +1,46 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest15 extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT m.*, m.icon AS micon, md.uid as md.uid, md.lastmsg,md.postnum," + // + "md.rvrc,md.money,md.credit,md.currency,md.lastvisit,md.thisvisit," + // + "md.onlinetime,md.lastpost,md.todaypost, md.monthpost,md.onlineip," + // + "md.uploadtime,md.uploadnum,md.starttime,md.pwdctime,md.monoltime," + // + "md.digests,md.f_num,md.creditpop, md.jobnum,md.lastgrab,md.follows,md.fans," + // + "md.newfans,md.newreferto,md.newcomment,md.postcheck,md.punch, mi.customdata " + // + "FROM pw_members m " + // + " LEFT JOIN pw_memberdata md ON m.uid=md.uid " + // + " LEFT JOIN pw_memberinfo mi ON mi.uid=m.uid " + // + "WHERE m.uid IN (?)")); // + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest16.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest16.java new file mode 100644 index 0000000000..5df90c4dab --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest16.java @@ -0,0 +1,37 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest16 extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "SELECT * FROM lhwbbs_threads_cate_index FORCE INDEX(PRIMARY) WHERE cid=? AND disabled=? ORDER BY tid DESC LIMIT ?,?")); // + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest17.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest17.java new file mode 100644 index 0000000000..3db1a565a7 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest17.java @@ -0,0 +1,37 @@ +/* + * 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.WallUtils; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest17 extends TestCase { + + public void test_true() throws Exception { + Assert.assertTrue(WallUtils.isValidateMySql(// + "DELETE FROM as_home_notification WHERE uid>? AND new=? AND dateline