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

4e0227
From c724812d9561021fb6a80c817d411d9ba2de5dbd Mon Sep 17 00:00:00 2001
4e0227
From: Phil Sutter <psutter@redhat.com>
4e0227
Date: Tue, 13 Jul 2021 13:54:12 +0200
4e0227
Subject: [PATCH] scanner: introduce start condition stack
4e0227
4e0227
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1979334
4e0227
Upstream Status: nftables commit 5896772fe3c5f
4e0227
4e0227
commit 5896772fe3c5f01696188ea04957a825ee601b12
4e0227
Author: Florian Westphal <fw@strlen.de>
4e0227
Date:   Mon Mar 8 18:18:33 2021 +0100
4e0227
4e0227
    scanner: introduce start condition stack
4e0227
4e0227
    Add a small initial chunk of flex start conditionals.
4e0227
4e0227
    This starts with two low-hanging fruits, numgen and j/symhash.
4e0227
4e0227
    NUMGEN and HASH start conditions are entered from flex when
4e0227
    the corresponding expression token is encountered.
4e0227
4e0227
    Flex returns to the INIT condition when the bison parser
4e0227
    has seen a complete numgen/hash statement.
4e0227
4e0227
    This intentionally uses a stack rather than BEGIN()
4e0227
    to eventually support nested states.
4e0227
4e0227
    The scanner_pop_start_cond() function argument is not used yet, but
4e0227
    will need to be used later to deal with nesting.
4e0227
4e0227
    Signed-off-by: Florian Westphal <fw@strlen.de>
4e0227
---
4e0227
 include/parser.h   |  8 ++++++++
4e0227
 src/parser_bison.y | 11 +++++++----
4e0227
 src/scanner.l      | 36 +++++++++++++++++++++++++++++-------
4e0227
 3 files changed, 44 insertions(+), 11 deletions(-)
4e0227
4e0227
diff --git a/include/parser.h b/include/parser.h
4e0227
index 949284d..1d293f5 100644
4e0227
--- a/include/parser.h
4e0227
+++ b/include/parser.h
4e0227
@@ -28,6 +28,12 @@ struct parser_state {
4e0227
 	struct list_head		*cmds;
4e0227
 };
4e0227
 
4e0227
+enum startcond_type {
4e0227
+	PARSER_SC_BEGIN,
4e0227
+	PARSER_SC_EXPR_HASH,
4e0227
+	PARSER_SC_EXPR_NUMGEN,
4e0227
+};
4e0227
+
4e0227
 struct mnl_socket;
4e0227
 
4e0227
 extern void parser_init(struct nft_ctx *nft, struct parser_state *state,
4e0227
@@ -47,4 +53,6 @@ extern void scanner_push_buffer(void *scanner,
4e0227
 				const struct input_descriptor *indesc,
4e0227
 				const char *buffer);
4e0227
 
4e0227
+extern void scanner_pop_start_cond(void *scanner, enum startcond_type sc);
4e0227
+
4e0227
 #endif /* NFTABLES_PARSER_H */
4e0227
diff --git a/src/parser_bison.y b/src/parser_bison.y
4e0227
index 5aedc55..9a9447f 100644
4e0227
--- a/src/parser_bison.y
4e0227
+++ b/src/parser_bison.y
4e0227
@@ -840,6 +840,9 @@ opt_newline		:	NEWLINE
4e0227
 		 	|	/* empty */
4e0227
 			;
4e0227
 
4e0227
+close_scope_hash	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_HASH); };
4e0227
+close_scope_numgen	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_NUMGEN); };
4e0227
+
4e0227
 common_block		:	INCLUDE		QUOTED_STRING	stmt_separator
4e0227
 			{
4e0227
 				if (scanner_include_file(nft, scanner, $2, &@$) < 0) {
4e0227
@@ -4249,7 +4252,7 @@ numgen_type		:	INC		{ $$ = NFT_NG_INCREMENTAL; }
4e0227
 			|	RANDOM		{ $$ = NFT_NG_RANDOM; }
4e0227
 			;
4e0227
 
4e0227
-numgen_expr		:	NUMGEN	numgen_type	MOD	NUM	offset_opt
4e0227
+numgen_expr		:	NUMGEN	numgen_type	MOD	NUM	offset_opt	close_scope_numgen
4e0227
 			{
4e0227
 				$$ = numgen_expr_alloc(&@$, $2, $4, $5);
4e0227
 			}
4e0227
@@ -4306,17 +4309,17 @@ xfrm_expr		:	IPSEC	xfrm_dir	xfrm_spnum	xfrm_state_key
4e0227
 			}
4e0227
 			;
4e0227
 
4e0227
-hash_expr		:	JHASH		expr	MOD	NUM	SEED	NUM	offset_opt
4e0227
+hash_expr		:	JHASH		expr	MOD	NUM	SEED	NUM	offset_opt	close_scope_hash
4e0227
 			{
4e0227
 				$$ = hash_expr_alloc(&@$, $4, true, $6, $7, NFT_HASH_JENKINS);
4e0227
 				$$->hash.expr = $2;
4e0227
 			}
4e0227
-			|	JHASH		expr	MOD	NUM	offset_opt
4e0227
+			|	JHASH		expr	MOD	NUM	offset_opt	close_scope_hash
4e0227
 			{
4e0227
 				$$ = hash_expr_alloc(&@$, $4, false, 0, $5, NFT_HASH_JENKINS);
4e0227
 				$$->hash.expr = $2;
4e0227
 			}
4e0227
-			|	SYMHASH		MOD	NUM	offset_opt
4e0227
+			|	SYMHASH		MOD	NUM	offset_opt	close_scope_hash
4e0227
 			{
4e0227
 				$$ = hash_expr_alloc(&@$, $3, false, 0, $4, NFT_HASH_SYM);
4e0227
 			}
4e0227
diff --git a/src/scanner.l b/src/scanner.l
4e0227
index 20b1b2d..68fe988 100644
4e0227
--- a/src/scanner.l
4e0227
+++ b/src/scanner.l
4e0227
@@ -98,6 +98,8 @@ static void reset_pos(struct parser_state *state, struct location *loc)
4e0227
 	state->indesc->column		= 1;
4e0227
 }
4e0227
 
4e0227
+static void scanner_push_start_cond(void *scanner, enum startcond_type type);
4e0227
+
4e0227
 #define YY_USER_ACTION {					\
4e0227
 	update_pos(yyget_extra(yyscanner), yylloc, yyleng);	\
4e0227
 	update_offset(yyget_extra(yyscanner), yylloc, yyleng);	\
4e0227
@@ -193,6 +195,9 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
4e0227
 %option yylineno
4e0227
 %option nodefault
4e0227
 %option warn
4e0227
+%option stack
4e0227
+%s SCANSTATE_EXPR_HASH
4e0227
+%s SCANSTATE_EXPR_NUMGEN
4e0227
 
4e0227
 %%
4e0227
 
4e0227
@@ -548,15 +553,21 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
4e0227
 "state"			{ return STATE; }
4e0227
 "status"		{ return STATUS; }
4e0227
 
4e0227
-"numgen"		{ return NUMGEN; }
4e0227
-"inc"			{ return INC; }
4e0227
-"mod"			{ return MOD; }
4e0227
-"offset"		{ return OFFSET; }
4e0227
+"numgen"		{ scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_NUMGEN); return NUMGEN; }
4e0227
+<SCANSTATE_EXPR_NUMGEN>{
4e0227
+	"inc"		{ return INC; }
4e0227
+}
4e0227
 
4e0227
-"jhash"			{ return JHASH; }
4e0227
-"symhash"		{ return SYMHASH; }
4e0227
-"seed"			{ return SEED; }
4e0227
+"jhash"			{ scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return JHASH; }
4e0227
+"symhash"		{ scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return SYMHASH; }
4e0227
 
4e0227
+<SCANSTATE_EXPR_HASH>{
4e0227
+	"seed"		{ return SEED; }
4e0227
+}
4e0227
+<SCANSTATE_EXPR_HASH,SCANSTATE_EXPR_NUMGEN>{
4e0227
+	"mod"		{ return MOD; }
4e0227
+	"offset"	{ return OFFSET; }
4e0227
+}
4e0227
 "dup"			{ return DUP; }
4e0227
 "fwd"			{ return FWD; }
4e0227
 
4e0227
@@ -949,3 +960,14 @@ void scanner_destroy(struct nft_ctx *nft)
4e0227
 	input_descriptor_list_destroy(state);
4e0227
 	yylex_destroy(nft->scanner);
4e0227
 }
4e0227
+
4e0227
+static void scanner_push_start_cond(void *scanner, enum startcond_type type)
4e0227
+{
4e0227
+	yy_push_state((int)type, scanner);
4e0227
+}
4e0227
+
4e0227
+void scanner_pop_start_cond(void *scanner, enum startcond_type t)
4e0227
+{
4e0227
+	yy_pop_state(scanner);
4e0227
+	(void)yy_top_state(scanner); /* suppress gcc warning wrt. unused function */
4e0227
+}
4e0227
-- 
4e0227
2.31.1
4e0227