mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 11:16:33 +03:00
change parsing of SetVar actions
Change tokenization of SetVar expressions and use syntax analyzer (seclang-parser) to process them. More precisely: 1 SetVar expression is tokenized in two modes, quoted and not quoted, depending on whether it started with single quote (') 2 Variable name and value can consist of multiple tokens, which are assembled back in syntax analyzer. This allows to support escapes (escape single/double quote, spaces etc.) and correctly detect where the expression ends. Fixes #1529
This commit is contained in:
parent
e0ebf28540
commit
0be821ded7
@ -649,6 +649,8 @@ using modsecurity::operators::Operator;
|
|||||||
RUN_TIME_VAR_TIME_SEC "RUN_TIME_VAR_TIME_SEC"
|
RUN_TIME_VAR_TIME_SEC "RUN_TIME_VAR_TIME_SEC"
|
||||||
RUN_TIME_VAR_TIME_WDAY "RUN_TIME_VAR_TIME_WDAY"
|
RUN_TIME_VAR_TIME_WDAY "RUN_TIME_VAR_TIME_WDAY"
|
||||||
RUN_TIME_VAR_TIME_YEAR "RUN_TIME_VAR_TIME_YEAR"
|
RUN_TIME_VAR_TIME_YEAR "RUN_TIME_VAR_TIME_YEAR"
|
||||||
|
SETVAR_VARIABLE_PART "SETVAR_VARIABLE_PART"
|
||||||
|
SETVAR_CONTENT_PART "SETVAR_CONTENT_PART"
|
||||||
VARIABLE "VARIABLE"
|
VARIABLE "VARIABLE"
|
||||||
DICT_ELEMENT "Dictionary element"
|
DICT_ELEMENT "Dictionary element"
|
||||||
DICT_ELEMENT_REGEXP "Dictionary element, selected by regexp"
|
DICT_ELEMENT_REGEXP "Dictionary element, selected by regexp"
|
||||||
@ -656,6 +658,10 @@ using modsecurity::operators::Operator;
|
|||||||
|
|
||||||
%type <std::unique_ptr<actions::Action>> act
|
%type <std::unique_ptr<actions::Action>> act
|
||||||
|
|
||||||
|
%type <std::unique_ptr<actions::Action>> setvar_action
|
||||||
|
%type <std::string> setvar_variable
|
||||||
|
%type <std::string> setvar_content
|
||||||
|
|
||||||
%type <std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > >
|
%type <std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > >
|
||||||
actions_may_quoted
|
actions_may_quoted
|
||||||
actions
|
actions
|
||||||
@ -2321,25 +2327,9 @@ act:
|
|||||||
{
|
{
|
||||||
ACTION_CONTAINER($$, new actions::SetUID($1));
|
ACTION_CONTAINER($$, new actions::SetUID($1));
|
||||||
}
|
}
|
||||||
| ACTION_SETVAR NOT VARIABLE
|
| ACTION_SETVAR setvar_action
|
||||||
{
|
{
|
||||||
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::unsetOperation, $3));
|
$$ = std::move($2);
|
||||||
}
|
|
||||||
| ACTION_SETVAR VARIABLE
|
|
||||||
{
|
|
||||||
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setToOneOperation, $2));
|
|
||||||
}
|
|
||||||
| ACTION_SETVAR VARIABLE SETVAR_OPERATION_EQUALS FREE_TEXT
|
|
||||||
{
|
|
||||||
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setOperation, $2, $4));
|
|
||||||
}
|
|
||||||
| ACTION_SETVAR VARIABLE SETVAR_OPERATION_EQUALS_PLUS FREE_TEXT
|
|
||||||
{
|
|
||||||
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::sumAndSetOperation, $2, $4));
|
|
||||||
}
|
|
||||||
| ACTION_SETVAR VARIABLE SETVAR_OPERATION_EQUALS_MINUS FREE_TEXT
|
|
||||||
{
|
|
||||||
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::substractAndSetOperation, $2, $4));
|
|
||||||
}
|
}
|
||||||
| ACTION_SEVERITY
|
| ACTION_SEVERITY
|
||||||
{
|
{
|
||||||
@ -2487,6 +2477,53 @@ act:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
setvar_action:
|
||||||
|
NOT setvar_variable
|
||||||
|
{
|
||||||
|
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::unsetOperation, $2));
|
||||||
|
}
|
||||||
|
| setvar_variable
|
||||||
|
{
|
||||||
|
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setToOneOperation, $1));
|
||||||
|
}
|
||||||
|
| setvar_variable SETVAR_OPERATION_EQUALS setvar_content
|
||||||
|
{
|
||||||
|
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setOperation, $1, $3));
|
||||||
|
}
|
||||||
|
| setvar_variable SETVAR_OPERATION_EQUALS_PLUS setvar_content
|
||||||
|
{
|
||||||
|
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::sumAndSetOperation, $1, $3));
|
||||||
|
}
|
||||||
|
| setvar_variable SETVAR_OPERATION_EQUALS_MINUS setvar_content
|
||||||
|
{
|
||||||
|
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::substractAndSetOperation, $1, $3));
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
setvar_variable:
|
||||||
|
SETVAR_VARIABLE_PART
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
SETVAR_VARIABLE_PART setvar_variable
|
||||||
|
{
|
||||||
|
$$ = $1 + $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
setvar_content:
|
||||||
|
SETVAR_CONTENT_PART
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
SETVAR_CONTENT_PART setvar_content
|
||||||
|
{
|
||||||
|
$$ = $1 + $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
void yy::seclang_parser::error (const location_type& l, const std::string& m) {
|
void yy::seclang_parser::error (const location_type& l, const std::string& m) {
|
||||||
|
@ -328,7 +328,8 @@ DICT_ELEMENT ([^\"|,\n \t]|([^\\]\\\"))+
|
|||||||
DICT_ELEMENT_WITH_PIPE [^ \t"]+
|
DICT_ELEMENT_WITH_PIPE [^ \t"]+
|
||||||
|
|
||||||
|
|
||||||
DICT_ELEMENT_TWO [^\"\=]+
|
DICT_ELEMENT_TWO [^\"\=, \t\r\n\\]*
|
||||||
|
DICT_ELEMENT_TWO_QUOTED [^\"\'\=\r\n\\]*
|
||||||
DICT_ELEMENT_TWO2 [A-Za-z_ -\%\{\.\}\-\/]+
|
DICT_ELEMENT_TWO2 [A-Za-z_ -\%\{\.\}\-\/]+
|
||||||
DIRECTIVE (?i:SecRule)
|
DIRECTIVE (?i:SecRule)
|
||||||
DIRECTIVE_SECRULESCRIPT (?i:SecRuleScript)
|
DIRECTIVE_SECRULESCRIPT (?i:SecRuleScript)
|
||||||
@ -370,9 +371,14 @@ EQUALS_MINUS (?i:=\-)
|
|||||||
%x FINISH_ACTIONS
|
%x FINISH_ACTIONS
|
||||||
%x LEXING_ERROR
|
%x LEXING_ERROR
|
||||||
%x LEXING_ERROR_ACTION
|
%x LEXING_ERROR_ACTION
|
||||||
%x SETVAR_ACTION_WAITING_VARIABLE
|
%x SETVAR_ACTION_NONQUOTED
|
||||||
%x SETVAR_ACTION_WAITING_OPERATION
|
%x SETVAR_ACTION_NONQUOTED_WAITING_COLLECTION_ELEM
|
||||||
%x SETVAR_ACTION_WAITING_CONTENT
|
%x SETVAR_ACTION_NONQUOTED_WAITING_OPERATION
|
||||||
|
%x SETVAR_ACTION_NONQUOTED_WAITING_CONTENT
|
||||||
|
%x SETVAR_ACTION_QUOTED
|
||||||
|
%x SETVAR_ACTION_QUOTED_WAITING_COLLECTION_ELEM
|
||||||
|
%x SETVAR_ACTION_QUOTED_WAITING_OPERATION
|
||||||
|
%x SETVAR_ACTION_QUOTED_WAITING_CONTENT
|
||||||
|
|
||||||
%{
|
%{
|
||||||
// Code run each time a pattern is matched.
|
// Code run each time a pattern is matched.
|
||||||
@ -452,7 +458,8 @@ EQUALS_MINUS (?i:=\-)
|
|||||||
{ACTION_SETUID}:'{VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_SETUID(yytext, *driver.loc.back()); }
|
{ACTION_SETUID}:'{VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_SETUID(yytext, *driver.loc.back()); }
|
||||||
{ACTION_SETUID}:{VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_SETUID(yytext, *driver.loc.back()); }
|
{ACTION_SETUID}:{VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_SETUID(yytext, *driver.loc.back()); }
|
||||||
|
|
||||||
{ACTION_SETVAR}: { BEGIN(SETVAR_ACTION_WAITING_VARIABLE); return p::make_ACTION_SETVAR(*driver.loc.back()); }
|
{ACTION_SETVAR}:' { BEGIN(SETVAR_ACTION_QUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); }
|
||||||
|
{ACTION_SETVAR}: { BEGIN(SETVAR_ACTION_NONQUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); }
|
||||||
|
|
||||||
|
|
||||||
{ACTION_SEVERITY}:'{ACTION_SEVERITY_VALUE}' { return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); }
|
{ACTION_SEVERITY}:'{ACTION_SEVERITY_VALUE}' { return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); }
|
||||||
@ -513,61 +520,61 @@ EQUALS_MINUS (?i:=\-)
|
|||||||
. { BEGIN(LEXING_ERROR_ACTION); yyless(0); }
|
. { BEGIN(LEXING_ERROR_ACTION); yyless(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
<SETVAR_ACTION_WAITING_VARIABLE>{
|
<SETVAR_ACTION_NONQUOTED>{
|
||||||
\'* { }
|
|
||||||
\"* { }
|
|
||||||
{NOT} { return p::make_NOT(*driver.loc.back()); }
|
{NOT} { return p::make_NOT(*driver.loc.back()); }
|
||||||
{VARIABLE_TX}(\:[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
{VARIABLE_TX}|{VARIABLE_SESSION}|{VARIABLE_RESOURCE}|{VARIABLE_IP}|{VARIABLE_USER}|{VARIABLE_GLOBAL}[:\.] { BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_COLLECTION_ELEM); return p::make_SETVAR_VARIABLE_PART(yytext, *driver.loc.back());}
|
||||||
{VARIABLE_TX}(\:{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
{VARIABLE_TX}|{VARIABLE_SESSION}|{VARIABLE_RESOURCE}|{VARIABLE_IP}|{VARIABLE_USER}|{VARIABLE_GLOBAL} { BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_OPERATION); return p::make_SETVAR_VARIABLE_PART(yytext, *driver.loc.back());}
|
||||||
{VARIABLE_TX}(\.[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
.|\n { BEGIN(LEXING_ERROR_ACTION); yyless(0); }
|
||||||
{VARIABLE_TX}(\.{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_SESSION}(\:[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_SESSION}(\:{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_SESSION}(\.[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_SESSION}(\.{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_RESOURCE}(\:[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_RESOURCE}(\:{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_RESOURCE}(\.[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_RESOURCE}(\.{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_IP}(\:[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_IP}(\:{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_IP}(\.[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_IP}(\.{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_USER}(\:[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_USER}(\:{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_USER}(\.[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_USER}(\.{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_GLOBAL}(\:[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_GLOBAL}(\:{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_GLOBAL}(\.[\']{DICT_ELEMENT_TWO}[\'])? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
{VARIABLE_GLOBAL}(\.{DICT_ELEMENT_TWO})? { BEGIN(SETVAR_ACTION_WAITING_OPERATION); return p::make_VARIABLE(yytext, *driver.loc.back()); }
|
|
||||||
. { BEGIN(LEXING_ERROR_ACTION); yyless(0); }
|
|
||||||
[ \t]*\\\n[ \t]* { driver.loc.back()->lines(1); driver.loc.back()->step(); }
|
|
||||||
[ \t]*\\\r\n[ \t]* { driver.loc.back()->lines(1); driver.loc.back()->step(); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<SETVAR_ACTION_NONQUOTED_WAITING_COLLECTION_ELEM>{
|
||||||
|
{DICT_ELEMENT_TWO} { return p::make_SETVAR_VARIABLE_PART(yytext, *driver.loc.back()); }
|
||||||
|
\\(.|\n) { return p::make_SETVAR_VARIABLE_PART(yytext + 1, *driver.loc.back()); }
|
||||||
<SETVAR_ACTION_WAITING_OPERATION>{
|
.|\n { BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_OPERATION); yyless(0); }
|
||||||
[ \t]*\n { BEGIN(INITIAL); yyless(1); }
|
|
||||||
[ \t]*\r\n { BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); }
|
|
||||||
[ \t]*\n { BEGIN(EXPECTING_ACTIONS); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); }
|
|
||||||
[ \t]*\r\n { BEGIN(EXPECTING_ACTIONS); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); }
|
|
||||||
[ \t]*\"[ \t]* { }
|
|
||||||
[ \t]*\'[ \t]* { }
|
|
||||||
\"[ \t]*\n { BEGIN(EXPECTING_ACTIONS); yyless(1); }
|
|
||||||
\"[ \t]*\r\n { BEGIN(EXPECTING_ACTIONS); driver.loc.back()->lines(1); driver.loc.back()->step(); }
|
|
||||||
{EQUALS_PLUS} { BEGIN(SETVAR_ACTION_WAITING_CONTENT); return p::make_SETVAR_OPERATION_EQUALS_PLUS(*driver.loc.back()); }
|
|
||||||
{EQUALS_MINUS} { BEGIN(SETVAR_ACTION_WAITING_CONTENT); return p::make_SETVAR_OPERATION_EQUALS_MINUS(*driver.loc.back()); }
|
|
||||||
{EQUALS} { BEGIN(SETVAR_ACTION_WAITING_CONTENT); return p::make_SETVAR_OPERATION_EQUALS(*driver.loc.back()); }
|
|
||||||
. { BEGIN(LEXING_ERROR_ACTION); yyless(0); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<SETVAR_ACTION_WAITING_CONTENT>{
|
<SETVAR_ACTION_NONQUOTED_WAITING_OPERATION>{
|
||||||
[^,"\n]+ { BEGIN(EXPECTING_ACTIONS); return p::make_FREE_TEXT(yytext, *driver.loc.back()); }
|
{EQUALS_PLUS} { BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_CONTENT); return p::make_SETVAR_OPERATION_EQUALS_PLUS(*driver.loc.back()); }
|
||||||
|
{EQUALS_MINUS} { BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_CONTENT); return p::make_SETVAR_OPERATION_EQUALS_MINUS(*driver.loc.back()); }
|
||||||
|
{EQUALS} { BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_CONTENT); return p::make_SETVAR_OPERATION_EQUALS(*driver.loc.back()); }
|
||||||
|
.|\n { BEGIN(EXPECTING_ACTIONS); yyless(0);}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<SETVAR_ACTION_NONQUOTED_WAITING_CONTENT>{
|
||||||
|
\\(.|\n) { return p::make_SETVAR_CONTENT_PART(yytext + 1, *driver.loc.back()); }
|
||||||
|
[^,"\n\r\t \\]+ { return p::make_SETVAR_CONTENT_PART(yytext, *driver.loc.back()); }
|
||||||
|
.|\n { BEGIN(EXPECTING_ACTIONS); yyless(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
<SETVAR_ACTION_QUOTED>{
|
||||||
|
{NOT} { return p::make_NOT(*driver.loc.back()); }
|
||||||
|
{VARIABLE_TX}|{VARIABLE_SESSION}|{VARIABLE_RESOURCE}|{VARIABLE_IP}|{VARIABLE_USER}|{VARIABLE_GLOBAL}[:\.] { BEGIN(SETVAR_ACTION_QUOTED_WAITING_COLLECTION_ELEM); return p::make_SETVAR_VARIABLE_PART(yytext, *driver.loc.back());}
|
||||||
|
{VARIABLE_TX}|{VARIABLE_SESSION}|{VARIABLE_RESOURCE}|{VARIABLE_IP}|{VARIABLE_USER}|{VARIABLE_GLOBAL} { BEGIN(SETVAR_ACTION_QUOTED_WAITING_OPERATION); return p::make_SETVAR_VARIABLE_PART(yytext, *driver.loc.back());}
|
||||||
|
.|\n { BEGIN(LEXING_ERROR_ACTION); yyless(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
<SETVAR_ACTION_QUOTED_WAITING_COLLECTION_ELEM>{
|
||||||
|
{DICT_ELEMENT_TWO_QUOTED} { return p::make_SETVAR_VARIABLE_PART(yytext, *driver.loc.back()); }
|
||||||
|
\\(.|\n) { return p::make_SETVAR_VARIABLE_PART(yytext + 1, *driver.loc.back()); }
|
||||||
|
.|\n { BEGIN(SETVAR_ACTION_QUOTED_WAITING_OPERATION); yyless(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
<SETVAR_ACTION_QUOTED_WAITING_OPERATION>{
|
||||||
|
{EQUALS_PLUS} { BEGIN(SETVAR_ACTION_QUOTED_WAITING_CONTENT); return p::make_SETVAR_OPERATION_EQUALS_PLUS(*driver.loc.back()); }
|
||||||
|
{EQUALS_MINUS} { BEGIN(SETVAR_ACTION_QUOTED_WAITING_CONTENT); return p::make_SETVAR_OPERATION_EQUALS_MINUS(*driver.loc.back()); }
|
||||||
|
{EQUALS} { BEGIN(SETVAR_ACTION_QUOTED_WAITING_CONTENT); return p::make_SETVAR_OPERATION_EQUALS(*driver.loc.back()); }
|
||||||
|
\' { BEGIN(EXPECTING_ACTIONS); }
|
||||||
|
.|\n { BEGIN(LEXING_ERROR_ACTION); yyless(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
<SETVAR_ACTION_QUOTED_WAITING_CONTENT>{
|
||||||
|
\\(.|\n) { return p::make_SETVAR_CONTENT_PART(yytext + 1, *driver.loc.back()); }
|
||||||
|
[^"\'\n\r\\]* { return p::make_SETVAR_CONTENT_PART(yytext, *driver.loc.back()); }
|
||||||
|
\' { BEGIN(EXPECTING_ACTIONS); }
|
||||||
|
.|\n { BEGIN(LEXING_ERROR_ACTION); yyless(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
<FINISH_ACTIONS>{
|
<FINISH_ACTIONS>{
|
||||||
<<EOF>> { BEGIN(INITIAL); yyless(0); p::make_NEW_LINE(*driver.loc.back()); }
|
<<EOF>> { BEGIN(INITIAL); yyless(0); p::make_NEW_LINE(*driver.loc.back()); }
|
||||||
. { BEGIN(INITIAL); }
|
. { BEGIN(INITIAL); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user