hush: fix bkslash+newline handling and number validation in ${NN} and ${#NN}
Entering "${1a}" into interactive shell was making it exit.
function                                             old     new   delta
parse_dollar                                         824     958    +134
i_getch_and_eat_bkslash_nl                             -      44     +44
parse_expr                                           917     938     +21
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 199/0)             Total: 199 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
			
			
This commit is contained in:
		
							
								
								
									
										4
									
								
								shell/ash_test/ash-parsing/bkslash_newline4.right
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								shell/ash_test/ash-parsing/bkslash_newline4.right
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| 1:1 | ||||
| 22:22 | ||||
| 3:3 | ||||
| Ok:0 | ||||
							
								
								
									
										14
									
								
								shell/ash_test/ash-parsing/bkslash_newline4.tests
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								shell/ash_test/ash-parsing/bkslash_newline4.tests
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| set -- 1 22 333 | ||||
| echo 1:$\ | ||||
| 1 | ||||
| echo 22:$\ | ||||
| {\ | ||||
| 2\ | ||||
| } | ||||
| echo 3:$\ | ||||
| {\ | ||||
| #\ | ||||
| 3\ | ||||
| } | ||||
| echo Ok:$\ | ||||
| ? | ||||
							
								
								
									
										28
									
								
								shell/hush.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								shell/hush.c
									
									
									
									
									
								
							| @@ -4998,6 +4998,32 @@ static int parse_dollar(o_string *as_string, | ||||
| 		 * which check invalid constructs like ${%}. | ||||
| 		 * Oh well... let's check that the var name part is fine... */ | ||||
|  | ||||
| 		if (isdigit(len_single_ch) | ||||
| 		 || (len_single_ch == '#' && isdigit(i_peek_and_eat_bkslash_nl(input))) | ||||
| 		) { | ||||
| 			/* Execution engine uses plain xatoi_positive() | ||||
| 			 * to interpret ${NNN} and {#NNN}, | ||||
| 			 * check syntax here in the parser. | ||||
| 			 * (bash does not support expressions in ${#NN}, | ||||
| 			 * e.g. ${#$var} and {#1:+WORD} are not supported). | ||||
| 			 */ | ||||
| 			unsigned cnt = 9; /* max 9 digits for ${NN} and 8 for {#NN} */ | ||||
| 			while (1) { | ||||
| 				o_addchr(dest, ch); | ||||
| 				debug_printf_parse(": '%c'\n", ch); | ||||
| 				ch = i_getch_and_eat_bkslash_nl(input); | ||||
| 				nommu_addchr(as_string, ch); | ||||
| 				if (ch == '}') | ||||
| 					break; | ||||
| 				if (--cnt == 0) | ||||
| 					goto bad_dollar_syntax; | ||||
| 				if (len_single_ch != '#' && strchr(VAR_SUBST_OPS, ch)) | ||||
| 					/* ${NN<op>...} is valid */ | ||||
| 					goto eat_until_closing; | ||||
| 				if (!isdigit(ch)) | ||||
| 					goto bad_dollar_syntax; | ||||
| 			} | ||||
| 		} else | ||||
| 		while (1) { | ||||
| 			unsigned pos; | ||||
|  | ||||
| @@ -5008,7 +5034,6 @@ static int parse_dollar(o_string *as_string, | ||||
| 			nommu_addchr(as_string, ch); | ||||
| 			if (ch == '}') | ||||
| 				break; | ||||
|  | ||||
| 			if (!isalnum(ch) && ch != '_') { | ||||
| 				unsigned end_ch; | ||||
| 				unsigned char last_ch; | ||||
| @@ -5027,6 +5052,7 @@ static int parse_dollar(o_string *as_string, | ||||
| 					 * special var name, e.g. ${#!}. | ||||
| 					 */ | ||||
| 				} | ||||
|  eat_until_closing: | ||||
| 				/* Eat everything until closing '}' (or ':') */ | ||||
| 				end_ch = '}'; | ||||
| 				if (BASH_SUBSTR | ||||
|   | ||||
							
								
								
									
										4
									
								
								shell/hush_test/hush-parsing/bkslash_newline4.right
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								shell/hush_test/hush-parsing/bkslash_newline4.right
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| 1:1 | ||||
| 22:22 | ||||
| 3:3 | ||||
| Ok:0 | ||||
							
								
								
									
										14
									
								
								shell/hush_test/hush-parsing/bkslash_newline4.tests
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								shell/hush_test/hush-parsing/bkslash_newline4.tests
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| set -- 1 22 333 | ||||
| echo 1:$\ | ||||
| 1 | ||||
| echo 22:$\ | ||||
| {\ | ||||
| 2\ | ||||
| } | ||||
| echo 3:$\ | ||||
| {\ | ||||
| #\ | ||||
| 3\ | ||||
| } | ||||
| echo Ok:$\ | ||||
| ? | ||||
| @@ -1,2 +1,2 @@ | ||||
| hush: invalid number '1q' | ||||
| hush: syntax error: unterminated ${name} | ||||
| hush: syntax error: unterminated ${name} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user