1From b1c9e9e889e4273fb15712051c887e6078511448 Mon Sep 17 00:00:00 2001 2From: Chris Coulson <chris.coulson@canonical.com> 3Date: Tue, 5 Jan 2021 22:17:28 +0000 4Subject: [PATCH] kern/parser: Introduce process_char() helper 5 6grub_parser_split_cmdline() iterates over each command line character. 7In order to add error checking and to simplify the subsequent error 8handling, split the character processing in to a separate function. 9 10Signed-off-by: Chris Coulson <chris.coulson@canonical.com> 11Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> 12Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com> 13--- 14 grub-core/kern/parser.c | 74 ++++++++++++++++++++++++++++++------------------- 15 1 file changed, 46 insertions(+), 28 deletions(-) 16 17diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c 18index 39e4df6..0d3582b 100644 19--- a/grub-core/kern/parser.c 20+++ b/grub-core/kern/parser.c 21@@ -1,7 +1,7 @@ 22 /* parser.c - the part of the parser that can return partial tokens */ 23 /* 24 * GRUB -- GRand Unified Bootloader 25- * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. 26+ * Copyright (C) 2005,2007,2009,2021 Free Software Foundation, Inc. 27 * 28 * GRUB is free software: you can redistribute it and/or modify 29 * it under the terms of the GNU General Public License as published by 30@@ -129,6 +129,46 @@ add_var (char *varname, char **bp, char **vp, 31 *((*bp)++) = *val; 32 } 33 34+static grub_err_t 35+process_char (char c, char *buffer, char **bp, char *varname, char **vp, 36+ grub_parser_state_t state, int *argc, 37+ grub_parser_state_t *newstate) 38+{ 39+ char use; 40+ 41+ *newstate = grub_parser_cmdline_state (state, c, &use); 42+ 43+ /* 44+ * If a variable was being processed and this character does 45+ * not describe the variable anymore, write the variable to 46+ * the buffer. 47+ */ 48+ add_var (varname, bp, vp, state, *newstate); 49+ 50+ if (check_varstate (*newstate)) 51+ { 52+ if (use) 53+ *((*vp)++) = use; 54+ } 55+ else if (*newstate == GRUB_PARSER_STATE_TEXT && 56+ state != GRUB_PARSER_STATE_ESC && grub_isspace (use)) 57+ { 58+ /* 59+ * Don't add more than one argument if multiple 60+ * spaces are used. 61+ */ 62+ if (*bp != buffer && *((*bp) - 1) != '\0') 63+ { 64+ *((*bp)++) = '\0'; 65+ (*argc)++; 66+ } 67+ } 68+ else if (use) 69+ *((*bp)++) = use; 70+ 71+ return GRUB_ERR_NONE; 72+} 73+ 74 grub_err_t 75 grub_parser_split_cmdline (const char *cmdline, 76 grub_reader_getline_t getline, void *getline_data, 77@@ -172,35 +212,13 @@ grub_parser_split_cmdline (const char *cmdline, 78 for (; *rp != '\0'; rp++) 79 { 80 grub_parser_state_t newstate; 81- char use; 82- 83- newstate = grub_parser_cmdline_state (state, *rp, &use); 84 85- /* If a variable was being processed and this character does 86- not describe the variable anymore, write the variable to 87- the buffer. */ 88- add_var (varname, &bp, &vp, state, newstate); 89- 90- if (check_varstate (newstate)) 91- { 92- if (use) 93- *(vp++) = use; 94- } 95- else 96+ if (process_char (*rp, buffer, &bp, varname, &vp, state, argc, 97+ &newstate) != GRUB_ERR_NONE) 98 { 99- if (newstate == GRUB_PARSER_STATE_TEXT 100- && state != GRUB_PARSER_STATE_ESC && grub_isspace (use)) 101- { 102- /* Don't add more than one argument if multiple 103- spaces are used. */ 104- if (bp != buffer && *(bp - 1)) 105- { 106- *(bp++) = '\0'; 107- (*argc)++; 108- } 109- } 110- else if (use) 111- *(bp++) = use; 112+ if (rd != cmdline) 113+ grub_free (rd); 114+ return grub_errno; 115 } 116 state = newstate; 117 } 118-- 1192.14.2 120 121