aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-22 11:41:18 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-22 11:41:18 +0000
commite1300f6fc7a16e7c91f666192e66798eb40965be (patch)
treefbc3de6459418736adb1087a914a6770a194a70e /shell/hush.c
parent786ce17d6d602c471aab3cbd6ea00c854bfe9366 (diff)
downloadbusybox-w32-e1300f6fc7a16e7c91f666192e66798eb40965be.tar.gz
busybox-w32-e1300f6fc7a16e7c91f666192e66798eb40965be.tar.bz2
busybox-w32-e1300f6fc7a16e7c91f666192e66798eb40965be.zip
hush: fix segv at repeated "set -- a b c" + "shift"
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 2c4704a9c..9c0cd7c8e 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -471,8 +471,10 @@ struct globals {
471 smallint fake_mode; 471 smallint fake_mode;
472 /* these three support $?, $#, and $1 */ 472 /* these three support $?, $#, and $1 */
473 smalluint last_return_code; 473 smalluint last_return_code;
474 /* is global_argv and global_argv[1..n] malloced? (note: not [0]) */
474 smalluint global_args_malloced; 475 smalluint global_args_malloced;
475 int global_argc; /* NB: $# + 1 */ 476 /* how many non-NULL argv's we have. NB: $# + 1 */
477 int global_argc;
476 char **global_argv; 478 char **global_argv;
477#if ENABLE_HUSH_LOOPS 479#if ENABLE_HUSH_LOOPS
478 unsigned depth_break_continue; 480 unsigned depth_break_continue;
@@ -4728,9 +4730,14 @@ static int builtin_shift(char **argv)
4728 n = atoi(argv[1]); 4730 n = atoi(argv[1]);
4729 } 4731 }
4730 if (n >= 0 && n < G.global_argc) { 4732 if (n >= 0 && n < G.global_argc) {
4731 G.global_argv[n] = G.global_argv[0]; 4733 if (G.global_args_malloced) {
4734 int m = 1;
4735 while (m <= n)
4736 free(G.global_argv[m++]);
4737 }
4732 G.global_argc -= n; 4738 G.global_argc -= n;
4733 G.global_argv += n; 4739 memmove(&G.global_argv[1], &G.global_argv[n+1],
4740 G.global_argc * sizeof(G.global_argv[0]));
4734 return EXIT_SUCCESS; 4741 return EXIT_SUCCESS;
4735 } 4742 }
4736 return EXIT_FAILURE; 4743 return EXIT_FAILURE;