• fix check for empty pattern in ${foo/bar/baz} expansion: the
character anchoring the pattern (‘#’ or ‘%’) must be skipped
  if one was used; fixes “BLA="#test"; echo "${BLA//#/}"” busy
  looping (due to null pattern) found by Jb_boin
			
			
This commit is contained in:
		
							
								
								
									
										41
									
								
								eval.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								eval.c
									
									
									
									
									
								
							| @@ -22,7 +22,7 @@ | |||||||
|  |  | ||||||
| #include "sh.h" | #include "sh.h" | ||||||
|  |  | ||||||
| __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.101 2011/03/16 20:31:33 tg Exp $"); | __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.102 2011/03/17 21:57:50 tg Exp $"); | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * string expansion |  * string expansion | ||||||
| @@ -464,12 +464,44 @@ expand(const char *cp,	/* input word */ | |||||||
| 						*d = '\0'; | 						*d = '\0'; | ||||||
| 						afree(tpat0, ATEMP); | 						afree(tpat0, ATEMP); | ||||||
|  |  | ||||||
| 						/* reject empty pattern */ | 						/* check for special cases */ | ||||||
| 						if (!*pat || gmatchx("", pat, false)) | 						d = str_val(st->var); | ||||||
|  | 						switch (*pat) { | ||||||
|  | 						case '#': | ||||||
|  | 							/* anchor at begin */ | ||||||
|  | 							tpat0 = pat + 1; | ||||||
|  | 							tpat1 = rrep; | ||||||
|  | 							tpat2 = d; | ||||||
|  | 							break; | ||||||
|  | 						case '%': | ||||||
|  | 							/* anchor at end */ | ||||||
|  | 							tpat0 = pat + 1; | ||||||
|  | 							tpat1 = d; | ||||||
|  | 							tpat2 = rrep; | ||||||
|  | 							break; | ||||||
|  | 						case '\0': | ||||||
|  | 							/* empty pattern */ | ||||||
| 							goto no_repl; | 							goto no_repl; | ||||||
|  | 						default: | ||||||
|  | 							tpat0 = pat; | ||||||
|  | 							/* silence gcc */ | ||||||
|  | 							tpat1 = tpat2 = NULL; | ||||||
|  | 						} | ||||||
|  | 						if (gmatchx(null, tpat0, false)) { | ||||||
|  | 							/* | ||||||
|  | 							 * pattern matches | ||||||
|  | 							 * the empty string | ||||||
|  | 							 */ | ||||||
|  | 							if (tpat0 == pat) | ||||||
|  | 								goto no_repl; | ||||||
|  | 							/* but is anchored */ | ||||||
|  | 							s = shf_smprintf("%s%s", | ||||||
|  | 							    tpat1, tpat2); | ||||||
|  | 							goto do_repl; | ||||||
|  | 						} | ||||||
|  |  | ||||||
| 						/* prepare string on which to work */ | 						/* prepare string on which to work */ | ||||||
| 						strdupx(s, str_val(st->var), ATEMP); | 						strdupx(s, d, ATEMP); | ||||||
| 						sbeg = s; | 						sbeg = s; | ||||||
|  |  | ||||||
| 						/* first see if we have any match at all */ | 						/* first see if we have any match at all */ | ||||||
| @@ -527,6 +559,7 @@ expand(const char *cp,	/* input word */ | |||||||
| 							goto again_repl; | 							goto again_repl; | ||||||
|  end_repl: |  end_repl: | ||||||
| 						afree(tpat1, ATEMP); | 						afree(tpat1, ATEMP); | ||||||
|  |  do_repl: | ||||||
| 						x.str = s; | 						x.str = s; | ||||||
|  no_repl: |  no_repl: | ||||||
| 						afree(pat, ATEMP); | 						afree(pat, ATEMP); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user