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

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