diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index 4e09ed9b45..679589675f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -448,7 +448,7 @@ public class MySqlLexer extends Lexer { return; } - if (!isAllowComment() && (isEOF() || !isSafeComment(stringVal))) { + if (!isHint && !isAllowComment() && (isEOF() || !isSafeComment(stringVal))) { throw new NotAllowCommentException(); } diff --git a/src/main/java/com/alibaba/druid/wall/WallProvider.java b/src/main/java/com/alibaba/druid/wall/WallProvider.java index 5f96c9f3ba..4b3f648d8b 100644 --- a/src/main/java/com/alibaba/druid/wall/WallProvider.java +++ b/src/main/java/com/alibaba/druid/wall/WallProvider.java @@ -15,21 +15,7 @@ */ package com.alibaba.druid.wall; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.SQLStatement; -import com.alibaba.druid.sql.parser.Lexer; -import com.alibaba.druid.sql.parser.NotAllowCommentException; -import com.alibaba.druid.sql.parser.ParserException; -import com.alibaba.druid.sql.parser.SQLStatementParser; -import com.alibaba.druid.sql.parser.Token; -import com.alibaba.druid.sql.visitor.ExportParameterVisitor; -import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; -import com.alibaba.druid.util.LRUCache; -import com.alibaba.druid.util.Utils; -import com.alibaba.druid.wall.spi.WallVisitorUtils; -import com.alibaba.druid.wall.violation.ErrorCode; -import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation; -import com.alibaba.druid.wall.violation.SyntaxErrorViolation; +import static com.alibaba.druid.util.JdbcSqlStatUtils.get; import java.security.PrivilegedAction; import java.util.ArrayList; @@ -44,7 +30,22 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import static com.alibaba.druid.util.JdbcSqlStatUtils.get; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement; +import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.NotAllowCommentException; +import com.alibaba.druid.sql.parser.ParserException; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.parser.Token; +import com.alibaba.druid.sql.visitor.ExportParameterVisitor; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.util.LRUCache; +import com.alibaba.druid.util.Utils; +import com.alibaba.druid.wall.spi.WallVisitorUtils; +import com.alibaba.druid.wall.violation.ErrorCode; +import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation; +import com.alibaba.druid.wall.violation.SyntaxErrorViolation; public abstract class WallProvider { @@ -640,7 +641,13 @@ public abstract class WallProvider { WallVisitor visitor = createWallVisitor(); if (statementList.size() > 0) { - for (SQLStatement stmt : statementList) { + boolean lastIsHint = false; + for (int i=0; i= 2) { - // if (context.getCommentCount() > 0) { - // violations.add(new IllegalSQLObjectViolation(ErrorCode.COMMIT_NOT_ALLOW, "comment not allow", sql)); - // } else if (context.getLikeNumberWarnings() > 0) { - // violations.add(new IllegalSQLObjectViolation(ErrorCode.COMMIT_NOT_ALLOW, "like number", sql)); - // } else { - // violations.add(new IllegalSQLObjectViolation(ErrorCode.COMPOUND, "multi-warnnings", sql)); - // } - // } - WallSqlStat sqlStat = null; if (violations.size() > 0) { violationCount.incrementAndGet(); diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/HintTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/HintTest.java deleted file mode 100644 index 87d520a19e..0000000000 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/HintTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.alibaba.druid.bvt.filter.wall; - -import junit.framework.TestCase; - -import org.junit.Assert; - -import com.alibaba.druid.wall.WallConfig; -import com.alibaba.druid.wall.WallUtils; - -public class HintTest extends TestCase { - - public void test_false() throws Exception { - WallConfig config = new WallConfig(); - config.setHintAllow(false); - String sql = "select * from person where id = '3'/**/union select 0,1,v from (select 1,2,user/*!() as v*/) a where '1'<>''"; - Assert.assertFalse(WallUtils.isValidateMySql(sql, config)); // - } - - public void test_false_1() throws Exception { - String sql = "select * from person where id = '3'/**/union select 0,1,v from (select 1,2,user/*!() as v*/) a where '1'<>''"; - Assert.assertFalse(WallUtils.isValidateMySql(sql)); // - } - - public void test_true() throws Exception { - String sql = "SELECT /*! STRAIGHT_JOIN */ col1 FROM table1,table2"; - Assert.assertTrue(WallUtils.isValidateMySql(sql)); // - } -} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_hint.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_hint.java new file mode 100644 index 0000000000..943fc2a24d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest_hint.java @@ -0,0 +1,57 @@ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallUtils; + +public class MySqlWallTest_hint extends TestCase { + + public void test_false() throws Exception { + WallConfig config = new WallConfig(); + config.setHintAllow(false); + String sql = "select * from person where id = '3'/**/union select 0,1,v from (select 1,2,user/*!() as v*/) a where '1'<>''"; + Assert.assertFalse(WallUtils.isValidateMySql(sql, config)); // + } + + public void test_false_1() throws Exception { + String sql = "select * from person where id = '3'/**/union select 0,1,v from (select 1,2,user/*!() as v*/) a where '1'<>''"; + Assert.assertFalse(WallUtils.isValidateMySql(sql)); // + } + + public void test_true() throws Exception { + String sql = "SELECT /*! STRAIGHT_JOIN */ col1 FROM table1,table2"; + Assert.assertTrue(WallUtils.isValidateMySql(sql)); // + } + + public void test_true_1() throws Exception { + String sql = "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */"; + Assert.assertTrue(WallUtils.isValidateMySql(sql)); // + } + + public void test_true_2() throws Exception { + String sql = "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */"; + Assert.assertTrue(WallUtils.isValidateMySql(sql)); // + } + + public void test_true_3() throws Exception { + WallConfig config = new WallConfig(); + config.setHintAllow(true); + config.setMultiStatementAllow(true); + String sql = " /*!50003 CREATE*/ /*!50020 /*!50003 PROCEDURE `top_calculate_customer_update`(in update_time DATETIME)" + + " DETERMINISTIC" + + " BEGIN" + + " DECLARE done INT DEFAULT FALSE;" + + " DECLARE c_receiver_city,c_receiver_district,c_receiver_address VARCHAR(200);" + + " DECLARE c_last_updated DATETIME;" + + " DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;" + + " insert into top_calculate_customer_log (execute_time,info) values (now(),'update table top_taobao_order_customer_mid begin');" + + " update top_tmp_order_middle_last_sync set status = 'wait', last_sync = update_time where plat_form = 'taobao' and status = 'blocking';" + + " END */"; + Assert.assertTrue(WallUtils.isValidateMySql(sql, config)); + } + + +}