Blame SOURCES/0022-scanner-introduce-start-condition-stack.patch

195495
From 80f3c19bc1b989ab7ba2b917193e8bd3f998ba39 Mon Sep 17 00:00:00 2001
195495
From: Florian Westphal <fw@strlen.de>
195495
Date: Mon, 8 Mar 2021 18:18:33 +0100
195495
Subject: [PATCH] scanner: introduce start condition stack
195495
195495
Add a small initial chunk of flex start conditionals.
195495
195495
This starts with two low-hanging fruits, numgen and j/symhash.
195495
195495
NUMGEN and HASH start conditions are entered from flex when
195495
the corresponding expression token is encountered.
195495
195495
Flex returns to the INIT condition when the bison parser
195495
has seen a complete numgen/hash statement.
195495
195495
This intentionally uses a stack rather than BEGIN()
195495
to eventually support nested states.
195495
195495
The scanner_pop_start_cond() function argument is not used yet, but
195495
will need to be used later to deal with nesting.
195495
195495
Signed-off-by: Florian Westphal <fw@strlen.de>
195495
(cherry picked from commit 5896772fe3c5f01696188ea04957a825ee601b12)
195495
---
195495
 include/parser.h   |  8 ++++++++
195495
 src/parser_bison.y | 11 +++++++----
195495
 src/scanner.l      | 36 +++++++++++++++++++++++++++++-------
195495
 3 files changed, 44 insertions(+), 11 deletions(-)
195495
195495
diff --git a/include/parser.h b/include/parser.h
195495
index 9baa3a4db789f..b2ebd7aa226c5 100644
195495
--- a/include/parser.h
195495
+++ b/include/parser.h
195495
@@ -26,6 +26,12 @@ struct parser_state {
195495
 	struct list_head		*cmds;
195495
 };
195495
 
195495
+enum startcond_type {
195495
+	PARSER_SC_BEGIN,
195495
+	PARSER_SC_EXPR_HASH,
195495
+	PARSER_SC_EXPR_NUMGEN,
195495
+};
195495
+
195495
 struct mnl_socket;
195495
 
195495
 extern void parser_init(struct nft_ctx *nft, struct parser_state *state,
195495
@@ -45,4 +51,6 @@ extern void scanner_push_buffer(void *scanner,
195495
 				const struct input_descriptor *indesc,
195495
 				const char *buffer);
195495
 
195495
+extern void scanner_pop_start_cond(void *scanner, enum startcond_type sc);
195495
+
195495
 #endif /* NFTABLES_PARSER_H */
195495
diff --git a/src/parser_bison.y b/src/parser_bison.y
195495
index 8644f66106496..da3fafcd1eeb1 100644
195495
--- a/src/parser_bison.y
195495
+++ b/src/parser_bison.y
195495
@@ -857,6 +857,9 @@ opt_newline		:	NEWLINE
195495
 		 	|	/* empty */
195495
 			;
195495
 
195495
+close_scope_hash	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_HASH); };
195495
+close_scope_numgen	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_NUMGEN); };
195495
+
195495
 common_block		:	INCLUDE		QUOTED_STRING	stmt_separator
195495
 			{
195495
 				if (scanner_include_file(nft, scanner, $2, &@$) < 0) {
195495
@@ -4811,7 +4814,7 @@ numgen_type		:	INC		{ $$ = NFT_NG_INCREMENTAL; }
195495
 			|	RANDOM		{ $$ = NFT_NG_RANDOM; }
195495
 			;
195495
 
195495
-numgen_expr		:	NUMGEN	numgen_type	MOD	NUM	offset_opt
195495
+numgen_expr		:	NUMGEN	numgen_type	MOD	NUM	offset_opt	close_scope_numgen
195495
 			{
195495
 				$$ = numgen_expr_alloc(&@$, $2, $4, $5);
195495
 			}
195495
@@ -4868,17 +4871,17 @@ xfrm_expr		:	IPSEC	xfrm_dir	xfrm_spnum	xfrm_state_key
195495
 			}
195495
 			;
195495
 
195495
-hash_expr		:	JHASH		expr	MOD	NUM	SEED	NUM	offset_opt
195495
+hash_expr		:	JHASH		expr	MOD	NUM	SEED	NUM	offset_opt	close_scope_hash
195495
 			{
195495
 				$$ = hash_expr_alloc(&@$, $4, true, $6, $7, NFT_HASH_JENKINS);
195495
 				$$->hash.expr = $2;
195495
 			}
195495
-			|	JHASH		expr	MOD	NUM	offset_opt
195495
+			|	JHASH		expr	MOD	NUM	offset_opt	close_scope_hash
195495
 			{
195495
 				$$ = hash_expr_alloc(&@$, $4, false, 0, $5, NFT_HASH_JENKINS);
195495
 				$$->hash.expr = $2;
195495
 			}
195495
-			|	SYMHASH		MOD	NUM	offset_opt
195495
+			|	SYMHASH		MOD	NUM	offset_opt	close_scope_hash
195495
 			{
195495
 				$$ = hash_expr_alloc(&@$, $3, false, 0, $4, NFT_HASH_SYM);
195495
 			}
195495
diff --git a/src/scanner.l b/src/scanner.l
195495
index 8bde1fbe912d8..ec8f252fbc8c8 100644
195495
--- a/src/scanner.l
195495
+++ b/src/scanner.l
195495
@@ -98,6 +98,8 @@ static void reset_pos(struct parser_state *state, struct location *loc)
195495
 	state->indesc->column		= 1;
195495
 }
195495
 
195495
+static void scanner_push_start_cond(void *scanner, enum startcond_type type);
195495
+
195495
 #define YY_USER_ACTION {					\
195495
 	update_pos(yyget_extra(yyscanner), yylloc, yyleng);	\
195495
 	update_offset(yyget_extra(yyscanner), yylloc, yyleng);	\
195495
@@ -193,6 +195,9 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
195495
 %option yylineno
195495
 %option nodefault
195495
 %option warn
195495
+%option stack
195495
+%s SCANSTATE_EXPR_HASH
195495
+%s SCANSTATE_EXPR_NUMGEN
195495
 
195495
 %%
195495
 
195495
@@ -551,15 +556,21 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
195495
 "state"			{ return STATE; }
195495
 "status"		{ return STATUS; }
195495
 
195495
-"numgen"		{ return NUMGEN; }
195495
-"inc"			{ return INC; }
195495
-"mod"			{ return MOD; }
195495
-"offset"		{ return OFFSET; }
195495
+"numgen"		{ scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_NUMGEN); return NUMGEN; }
195495
+<SCANSTATE_EXPR_NUMGEN>{
195495
+	"inc"		{ return INC; }
195495
+}
195495
 
195495
-"jhash"			{ return JHASH; }
195495
-"symhash"		{ return SYMHASH; }
195495
-"seed"			{ return SEED; }
195495
+"jhash"			{ scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return JHASH; }
195495
+"symhash"		{ scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return SYMHASH; }
195495
 
195495
+<SCANSTATE_EXPR_HASH>{
195495
+	"seed"		{ return SEED; }
195495
+}
195495
+<SCANSTATE_EXPR_HASH,SCANSTATE_EXPR_NUMGEN>{
195495
+	"mod"		{ return MOD; }
195495
+	"offset"	{ return OFFSET; }
195495
+}
195495
 "dup"			{ return DUP; }
195495
 "fwd"			{ return FWD; }
195495
 
195495
@@ -973,3 +984,14 @@ void scanner_destroy(struct nft_ctx *nft)
195495
 	input_descriptor_list_destroy(state);
195495
 	yylex_destroy(nft->scanner);
195495
 }
195495
+
195495
+static void scanner_push_start_cond(void *scanner, enum startcond_type type)
195495
+{
195495
+	yy_push_state((int)type, scanner);
195495
+}
195495
+
195495
+void scanner_pop_start_cond(void *scanner, enum startcond_type t)
195495
+{
195495
+	yy_pop_state(scanner);
195495
+	(void)yy_top_state(scanner); /* suppress gcc warning wrt. unused function */
195495
+}
195495
-- 
195495
2.33.0
195495