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

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