diff --git a/src/parser/scanner.lex b/src/parser/scanner.lex index 4fe773332d2..122152fe13d 100644 --- a/src/parser/scanner.lex +++ b/src/parser/scanner.lex @@ -21,6 +21,7 @@ static constexpr size_t MAX_STRING = 4096; %x DQ_STR %x SQ_STR +%x LB_STR %x COMMENT blanks ([ \t\n]+) @@ -327,17 +328,19 @@ CHINESE_LABEL ({U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U})+ } return TokenType::LABEL; } -\`{LABEL}\` { - yylval->strval = new std::string(yytext + 1, yyleng - 2); +\` { BEGIN(LB_STR); sbufPos_ = 0; } +\` { + yylval->strval = new std::string(sbuf(), sbufPos_); + BEGIN(INITIAL); if (yylval->strval->size() > MAX_STRING) { auto error = "Out of range of the LABEL length, " - "the max length of LABEL is " + - std::to_string(MAX_STRING) + ":"; + "the max length of LABEL is " + + std::to_string(MAX_STRING) + ":"; delete yylval->strval; throw GraphParser::syntax_error(*yylloc, error); } return TokenType::LABEL; - } + } {IP_OCTET}(\.{IP_OCTET}){3} { yylval->strval = new std::string(yytext, yyleng); return TokenType::IPV4; @@ -382,11 +385,11 @@ CHINESE_LABEL ({U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U})+ BEGIN(INITIAL); return TokenType::STRING; } -<> { +<> { // Must match '' or "" throw GraphParser::syntax_error(*yylloc, "Unterminated string: "); } -\n { yyterminate(); } +\n { yyterminate(); } [^\\\n\"]+ { makeSpaceForString(yyleng); ::strncpy(sbuf() + sbufPos_, yytext, yyleng); @@ -397,7 +400,12 @@ CHINESE_LABEL ({U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U})+ ::strncpy(sbuf() + sbufPos_, yytext, yyleng); sbufPos_ += yyleng; } -\\{OCT}{1,3} { +[^\\\n\`]+ { + makeSpaceForString(yyleng); + ::strncpy(sbuf() + sbufPos_, yytext, yyleng); + sbufPos_ += yyleng; + } +\\{OCT}{1,3} { if (FLAGS_disable_octal_escape_char) { makeSpaceForString(yyleng); ::strncpy(sbuf() + sbufPos_, yytext, yyleng); @@ -412,7 +420,7 @@ CHINESE_LABEL ({U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U})+ sbuf()[sbufPos_++] = val; } } -\\{DEC}+ { +\\{DEC}+ { if (FLAGS_disable_octal_escape_char) { makeSpaceForString(yyleng); ::strncpy(sbuf() + sbufPos_, yytext, yyleng); @@ -421,37 +429,37 @@ CHINESE_LABEL ({U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U})+ yyterminate(); } } -\\[uUxX]{HEX}{4} { +\\[uUxX]{HEX}{4} { auto encoded = folly::codePointToUtf8(std::strtoul(yytext+2, nullptr, 16)); makeSpaceForString(encoded.size()); ::strncpy(sbuf() + sbufPos_, encoded.data(), encoded.size()); sbufPos_ += encoded.size(); } -\\n { +\\n { makeSpaceForString(1); sbuf()[sbufPos_++] = '\n'; } -\\t { +\\t { makeSpaceForString(1); sbuf()[sbufPos_++] = '\t'; } -\\r { +\\r { makeSpaceForString(1); sbuf()[sbufPos_++] = '\r'; } -\\b { +\\b { makeSpaceForString(1); sbuf()[sbufPos_++] = '\b'; } -\\f { +\\f { makeSpaceForString(1); sbuf()[sbufPos_++] = '\f'; } -\\(.|\n) { +\\(.|\n) { makeSpaceForString(1); sbuf()[sbufPos_++] = yytext[1]; } -\\ { +\\ { // This rule should have never been matched, // but without this, it somehow triggers the `nodefault' warning of flex. yyterminate(); diff --git a/src/parser/test/ParserTest.cpp b/src/parser/test/ParserTest.cpp index 940686fe6b7..67bf59fd4c6 100644 --- a/src/parser/test/ParserTest.cpp +++ b/src/parser/test/ParserTest.cpp @@ -3112,4 +3112,17 @@ TEST_F(ParserTest, DetectMemoryLeakTest) { } } +TEST_F(ParserTest, TestNameLabel) { + { + std::string query = "CREATE TAG person127.0.0.1(name STRING);"; + auto result = parse(query); + ASSERT_FALSE(result.ok()) << result.status(); + } + { + std::string query = "CREATE TAG `person127.0.0.1`(name STRING);"; + auto result = parse(query); + ASSERT_TRUE(result.ok()) << result.status(); + } +} + } // namespace nebula