[OpenWrt-Devel] [PATCH] busybox: replace hotfix with upstream commit de5edadee2dca2896492f97ab3a56e389305e74d

John Crispin blogic at openwrt.org
Tue Jul 7 08:19:11 EDT 2015


when applying the patch i get

patching file
package/utils/busybox/patches/290-ash-fix-a-regression-in-handling-local-variables.patch
patching file
package/utils/busybox/patches/290-ash-fix-handling-of-duplicate-local.patch
patch: **** malformed patch at line 301: --





On 23/04/2015 13:22, Bastian Bittorf wrote:
> with this patch the hotfix from r45471 is replaced.
> 
> compile and runtested with ar71xx / r45568
> 
> the file 'shell/ash_test/ash-heredoc/heredoc1.right' is
> not included, because it does not apply on our busybox.
> when upgrading to next busybox-release, this patch can be dropped.
> 
> Signed-off-by: Bastian Bittorf <bittorf at bluebottle.com>
> ---
>  ...-a-regression-in-handling-local-variables.patch |   75 -------
>  .../290-ash-fix-handling-of-duplicate-local.patch  |  204 ++++++++++++++++++++
>  2 files changed, 204 insertions(+), 75 deletions(-)
>  delete mode 100644 package/utils/busybox/patches/290-ash-fix-a-regression-in-handling-local-variables.patch
>  create mode 100644 package/utils/busybox/patches/290-ash-fix-handling-of-duplicate-local.patch
> 
> diff --git a/package/utils/busybox/patches/290-ash-fix-a-regression-in-handling-local-variables.patch b/package/utils/busybox/patches/290-ash-fix-a-regression-in-handling-local-variables.patch
> deleted file mode 100644
> index 0ac1925..0000000
> --- a/package/utils/busybox/patches/290-ash-fix-a-regression-in-handling-local-variables.patch
> +++ /dev/null
> @@ -1,75 +0,0 @@
> -From: Felix Fietkau <nbd at openwrt.org>
> -Date: Fri, 17 Apr 2015 01:54:51 +0200
> -Subject: [PATCH] ash: fix a regression in handling local variables
> -
> -commit 109ee5d33694a03cda3424b4846584250832ba8e
> -"ash: make "locak VAR" unset VAR (bash does that)"
> -
> -This commit introduced a regression where calling local on an already
> -local variable unsets it. This does not match bash behavior.
> -
> -Update test case to check for this behavior
> -
> -Signed-off-by: Felix Fietkau <nbd at openwrt.org>
> ----
> -
> ---- a/shell/ash.c
> -+++ b/shell/ash.c
> -@@ -8961,6 +8961,21 @@ parse_command_args(char **argv, const ch
> - }
> - #endif
> - 
> -+static bool
> -+findlocal(struct var *vp)
> -+{
> -+	struct localvar *lvp = localvars;
> -+
> -+	while (lvp) {
> -+		if (lvp->vp == vp)
> -+			return true;
> -+
> -+		lvp = lvp->next;
> -+	}
> -+
> -+	return false;
> -+}
> -+
> - /*
> -  * Make a variable a local variable.  When a variable is made local, it's
> -  * value and flags are saved in a localvar structure.  The saved values
> -@@ -9000,7 +9015,7 @@ mklocal(char *name)
> - 			vp->flags |= VSTRFIXED|VTEXTFIXED;
> - 			if (eq)
> - 				setvareq(name, 0);
> --			else
> -+			else if (!findlocal(vp))
> - 				/* "local VAR" unsets VAR: */
> - 				setvar(name, NULL, 0);
> - 		}
> ---- a/shell/ash_test/ash-misc/local1.right
> -+++ b/shell/ash_test/ash-misc/local1.right
> -@@ -1,4 +1,5 @@
> - A1:'A'
> - A2:''
> --A3:''
> --A4:'A'
> -+A3:'B'
> -+A4:''
> -+A5:'A'
> ---- a/shell/ash_test/ash-misc/local1.tests
> -+++ b/shell/ash_test/ash-misc/local1.tests
> -@@ -3,9 +3,12 @@ f() {
> - 	local a
> - 	# the above line unsets $a
> - 	echo "A2:'$a'"
> --	unset a
> -+	a=B
> -+	local a
> - 	echo "A3:'$a'"
> -+	unset a
> -+	echo "A4:'$a'"
> - }
> - echo "A1:'$a'"
> - f
> --echo "A4:'$a'"
> -+echo "A5:'$a'"
> diff --git a/package/utils/busybox/patches/290-ash-fix-handling-of-duplicate-local.patch b/package/utils/busybox/patches/290-ash-fix-handling-of-duplicate-local.patch
> new file mode 100644
> index 0000000..71c2162
> --- /dev/null
> +++ b/package/utils/busybox/patches/290-ash-fix-handling-of-duplicate-local.patch
> @@ -0,0 +1,204 @@
> +From 0a0acb55db8d7c4dec445573f1b0528d126b9e1f Mon Sep 17 00:00:00 2001
> +From: Denys Vlasenko <vda.linux at googlemail.com>
> +Date: Sat, 18 Apr 2015 19:36:38 +0200
> +Subject: [PATCH] ash: fix handling of duplicate "local"
> +
> +Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
> +---
> + shell/ash.c                               | 51 +++++++++++++++++++++----------
> + shell/ash_test/ash-vars/var3.right        |  5 +++
> + shell/ash_test/ash-vars/var3.tests        |  1 +
> + 4 files changed, 42 insertions(+), 17 deletions(-)
> + create mode 100644 shell/ash_test/ash-vars/var3.right
> + create mode 100755 shell/ash_test/ash-vars/var3.tests
> +
> +diff --git a/shell/ash.c b/shell/ash.c
> +index b568013..697a64f 100644
> +--- a/shell/ash.c
> ++++ b/shell/ash.c
> +@@ -2030,7 +2030,7 @@ varcmp(const char *p, const char *q)
> + 	int c, d;
> + 
> + 	while ((c = *p) == (d = *q)) {
> +-		if (!c || c == '=')
> ++		if (c == '\0' || c == '=')
> + 			goto out;
> + 		p++;
> + 		q++;
> +@@ -2247,7 +2247,7 @@ setvar(const char *name, const char *val, int flags)
> + }
> + 
> + static void FAST_FUNC
> +-setvar2(const char *name, const char *val)
> ++setvar0(const char *name, const char *val)
> + {
> + 	setvar(name, val, 0);
> + }
> +@@ -2310,7 +2310,7 @@ unsetvar(const char *s)
> + 			free(vp);
> + 			INT_ON;
> + 		} else {
> +-			setvar2(s, 0);
> ++			setvar0(s, NULL);
> + 			vp->flags &= ~VEXPORT;
> + 		}
> +  ok:
> +@@ -5505,7 +5505,7 @@ ash_arith(const char *s)
> + 	arith_t result;
> + 
> + 	math_state.lookupvar = lookupvar;
> +-	math_state.setvar    = setvar2;
> ++	math_state.setvar    = setvar0;
> + 	//math_state.endofname = endofname;
> + 
> + 	INT_OFF;
> +@@ -6360,7 +6360,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
> + 
> + 	switch (subtype) {
> + 	case VSASSIGN:
> +-		setvar2(varname, startp);
> ++		setvar0(varname, startp);
> + 		amount = startp - expdest;
> + 		STADJUST(amount, expdest);
> + 		return startp;
> +@@ -8591,7 +8591,7 @@ evalfor(union node *n, int flags)
> + 	loopnest++;
> + 	flags &= EV_TESTED;
> + 	for (sp = arglist.list; sp; sp = sp->next) {
> +-		setvar2(n->nfor.var, sp->text);
> ++		setvar0(n->nfor.var, sp->text);
> + 		evaltree(n->nfor.body, flags);
> + 		if (evalskip) {
> + 			if (evalskip == SKIPCONT && --skipcount <= 0) {
> +@@ -8970,21 +8970,37 @@ mklocal(char *name)
> + 	struct localvar *lvp;
> + 	struct var **vpp;
> + 	struct var *vp;
> ++	char *eq = strchr(name, '=');
> + 
> + 	INT_OFF;
> +-	lvp = ckzalloc(sizeof(struct localvar));
> ++	/* Cater for duplicate "local". Examples:
> ++	 * x=0; f() { local x=1; echo $x; local x; echo $x; }; f; echo $x
> ++	 * x=0; f() { local x=1; echo $x; local x=2; echo $x; }; f; echo $x
> ++	 */
> ++	lvp = localvars;
> ++	while (lvp) {
> ++		if (varcmp(lvp->vp->var_text, name) == 0) {
> ++			if (eq)
> ++				setvareq(name, 0);
> ++			/* else:
> ++			 * it's a duplicate "local VAR" declaration, do nothing
> ++			 */
> ++			return;
> ++		}
> ++		lvp = lvp->next;
> ++	}
> ++
> ++	lvp = ckzalloc(sizeof(*lvp));
> + 	if (LONE_DASH(name)) {
> + 		char *p;
> + 		p = ckmalloc(sizeof(optlist));
> + 		lvp->text = memcpy(p, optlist, sizeof(optlist));
> + 		vp = NULL;
> + 	} else {
> +-		char *eq;
> +-
> + 		vpp = hashvar(name);
> + 		vp = *findvar(vpp, name);
> +-		eq = strchr(name, '=');
> + 		if (vp == NULL) {
> ++			/* variable did not exist yet */
> + 			if (eq)
> + 				setvareq(name, VSTRFIXED);
> + 			else
> +@@ -8994,12 +9010,15 @@ mklocal(char *name)
> + 		} else {
> + 			lvp->text = vp->var_text;
> + 			lvp->flags = vp->flags;
> ++			/* make sure neither "struct var" nor string gets freed
> ++			 * during (un)setting:
> ++			 */
> + 			vp->flags |= VSTRFIXED|VTEXTFIXED;
> + 			if (eq)
> + 				setvareq(name, 0);
> + 			else
> + 				/* "local VAR" unsets VAR: */
> +-				setvar(name, NULL, 0);
> ++				setvar0(name, NULL);
> + 		}
> + 	}
> + 	lvp->vp = vp;
> +@@ -9491,7 +9510,7 @@ evalcommand(union node *cmd, int flags)
> + 		 * '_' in 'vi' command mode during line editing...
> + 		 * However I implemented that within libedit itself.
> + 		 */
> +-		setvar2("_", lastarg);
> ++		setvar0("_", lastarg);
> + 	}
> + 	popstackmark(&smark);
> + }
> +@@ -12885,7 +12904,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
> + 	 * to jump out of it.
> + 	 */
> + 	INT_OFF;
> +-	r = shell_builtin_read(setvar2,
> ++	r = shell_builtin_read(setvar0,
> + 		argptr,
> + 		bltinlookup("IFS"), /* can be NULL */
> + 		read_flags,
> +@@ -13046,14 +13065,14 @@ init(void)
> + 			}
> + 		}
> + 
> +-		setvar2("PPID", utoa(getppid()));
> ++		setvar0("PPID", utoa(getppid()));
> + #if ENABLE_ASH_BASH_COMPAT
> + 		p = lookupvar("SHLVL");
> + 		setvar("SHLVL", utoa((p ? atoi(p) : 0) + 1), VEXPORT);
> + 		if (!lookupvar("HOSTNAME")) {
> + 			struct utsname uts;
> + 			uname(&uts);
> +-			setvar2("HOSTNAME", uts.nodename);
> ++			setvar0("HOSTNAME", uts.nodename);
> + 		}
> + #endif
> + 		p = lookupvar("PWD");
> +@@ -13309,7 +13328,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
> + 				hp = lookupvar("HOME");
> + 				if (hp) {
> + 					hp = concat_path_file(hp, ".ash_history");
> +-					setvar2("HISTFILE", hp);
> ++					setvar0("HISTFILE", hp);
> + 					free((char*)hp);
> + 					hp = lookupvar("HISTFILE");
> + 				}
> +diff --git a/shell/ash_test/ash-vars/var3.tests b/shell/ash_test/ash-vars/var3.tests
> +new file mode 100755
> +index 0000000..97b102c
> +--- /dev/null
> ++++ b/shell/ash_test/ash-vars/var3.tests
> +@@ -0,0 +1 @@
> ++x=0; f() { local x=1; echo $x; local x; echo $x; unset x; echo $x; local x; echo $x; }; f; echo $x
> +-- 
> +1.8.1.2
> +
> 
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list