From da75f4484469ca0122b80de69bf3b75a6be71efc Mon Sep 17 00:00:00 2001 From: Andreas Bühmann Date: Thu, 24 Jun 2010 04:32:37 +0200 Subject: ash: <> redir should not truncate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Bühmann Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shell/ash.c') diff --git a/shell/ash.c b/shell/ash.c index f581b5bdf..1f8f90a09 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -4938,7 +4938,7 @@ openredirect(union node *redir) break; case NFROMTO: fname = redir->nfile.expfname; - f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666); + f = open(fname, O_RDWR|O_CREAT, 0666); if (f < 0) goto ecreate; break; -- cgit v1.2.3-55-g6feb From 1fcbff2fac490f5665fc1ed13ddad766a8879f3b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 26 Jun 2010 02:40:08 +0200 Subject: build system: do not rebuild ash and hush on any change to any .c file Signed-off-by: Denys Vlasenko --- applets/Kbuild.src | 2 +- applets/applet_tables.c | 24 ++++++++++++++++++++++-- libbb/appletlib.c | 2 +- shell/ash.c | 4 +--- shell/hush.c | 4 +--- 5 files changed, 26 insertions(+), 10 deletions(-) (limited to 'shell/ash.c') diff --git a/applets/Kbuild.src b/applets/Kbuild.src index e3bac9681..31fee8d1e 100644 --- a/applets/Kbuild.src +++ b/applets/Kbuild.src @@ -38,7 +38,7 @@ include/usage_compressed.h: applets/usage $(srctree_slash)applets/usage_compress $(call cmd,gen_usage_compressed) quiet_cmd_gen_applet_tables = GEN include/applet_tables.h - cmd_gen_applet_tables = applets/applet_tables include/applet_tables.h + cmd_gen_applet_tables = applets/applet_tables include/applet_tables.h include/NUM_APPLETS.h include/applet_tables.h: applets/applet_tables $(call cmd,gen_applet_tables) diff --git a/applets/applet_tables.c b/applets/applet_tables.c index e48be4682..338dc20f9 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c @@ -79,7 +79,7 @@ int main(int argc, char **argv) } printf("\n"); - printf("#ifndef SKIP_definitions\n"); + //printf("#ifndef SKIP_definitions\n"); printf("const char applet_names[] ALIGN1 = \"\"\n"); for (i = 0; i < NUM_APPLETS; i++) { printf("\"%s\" \"\\0\"\n", applets[i].name); @@ -123,9 +123,29 @@ int main(int argc, char **argv) } printf("};\n"); #endif - printf("#endif /* SKIP_definitions */\n"); + //printf("#endif /* SKIP_definitions */\n"); printf("\n"); printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN); + if (argv[2]) { + char line_old[80]; + char line_new[80]; + FILE *fp; + + line_old[0] = 0; + fp = fopen(argv[2], "r"); + if (fp) { + fgets(line_old, sizeof(line_old), fp); + fclose(fp); + } + sprintf(line_new, "#define NUM_APPLETS %u\n", NUM_APPLETS); + if (strcmp(line_old, line_new) != 0) { + fp = fopen(argv[2], "w"); + if (!fp) + return 1; + fputs(line_new, fp); + } + } + return 0; } diff --git a/libbb/appletlib.c b/libbb/appletlib.c index f3d530184..58f1a9490 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -61,7 +61,7 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; #else # define usage_messages 0 -#endif /* SHOW_USAGE */ +#endif #if ENABLE_FEATURE_COMPRESS_USAGE diff --git a/shell/ash.c b/shell/ash.c index 1f8f90a09..cfd8154ef 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -50,9 +50,7 @@ # define CLEAR_RANDOM_T(rnd) ((void)0) #endif -#define SKIP_definitions 1 -#include "applet_tables.h" -#undef SKIP_definitions +#include "NUM_APPLETS.h" #if NUM_APPLETS == 1 /* STANDALONE does not make sense, and won't compile */ # undef CONFIG_FEATURE_SH_STANDALONE diff --git a/shell/hush.c b/shell/hush.c index e64c923b4..29ff3c442 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -128,9 +128,7 @@ # define USE_FOR_MMU(...) #endif -#define SKIP_definitions 1 -#include "applet_tables.h" -#undef SKIP_definitions +#include "NUM_APPLETS.h" #if NUM_APPLETS == 1 /* STANDALONE does not make sense, and won't compile */ # undef CONFIG_FEATURE_SH_STANDALONE -- cgit v1.2.3-55-g6feb From fd33e17a2bf4c09bb12ac09a645cfd0f0f914fec Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 26 Jun 2010 22:55:44 +0200 Subject: ash: fix obscure case of replacing + globbing + backslashes function old new delta subevalvar 1152 1178 +26 readtoken1 3267 3275 +8 redirect 1284 1286 +2 expandarg 957 958 +1 expdir 4 - -4 evalcommand 1219 1209 -10 expmeta 481 469 -12 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 4/2 up/down: 37/-26) Total: 11 bytes Signed-off-by: Denys Vlasenko --- shell/ash.c | 42 +++++++++++----------- .../ash-quoting/dollar_repl_slash_bash1.right | 10 ++++++ .../ash-quoting/dollar_repl_slash_bash1.tests | 21 +++++++++++ 3 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 shell/ash_test/ash-quoting/dollar_repl_slash_bash1.right create mode 100755 shell/ash_test/ash-quoting/dollar_repl_slash_bash1.tests (limited to 'shell/ash.c') diff --git a/shell/ash.c b/shell/ash.c index cfd8154ef..0337a5535 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -6184,8 +6184,7 @@ subevalvar(char *p, char *str, int strloc, int subtype, char *startp; char *loc; char *rmesc, *rmescend; - IF_ASH_BASH_COMPAT(char *repl = NULL;) - IF_ASH_BASH_COMPAT(char null = '\0';) + IF_ASH_BASH_COMPAT(const char *repl = NULL;) IF_ASH_BASH_COMPAT(int pos, len, orig_len;) int saveherefd = herefd; int amount, workloc, resetloc; @@ -6306,7 +6305,7 @@ subevalvar(char *p, char *str, int strloc, int subtype, if (!repl) { repl = parse_sub_pattern(str, varflags & VSQUOTE); if (!repl) - repl = &null; + repl = nullstr; } /* If there's no pattern to match, return the expansion unmolested */ @@ -6357,8 +6356,12 @@ subevalvar(char *p, char *str, int strloc, int subtype, idx = loc; } - for (loc = repl; *loc; loc++) { + for (loc = (char*)repl; *loc; loc++) { char *restart_detect = stackblock(); + if (quotes && *loc == '\\') { + STPUTC(CTLESC, expdest); + len++; + } STPUTC(*loc, expdest); if (stackblock() != restart_detect) goto restart; @@ -6368,6 +6371,10 @@ subevalvar(char *p, char *str, int strloc, int subtype, if (subtype == VSREPLACE) { while (*idx) { char *restart_detect = stackblock(); + if (quotes && *idx == '\\') { + STPUTC(CTLESC, expdest); + len++; + } STPUTC(*idx, expdest); if (stackblock() != restart_detect) goto restart; @@ -6381,11 +6388,10 @@ subevalvar(char *p, char *str, int strloc, int subtype, /* We've put the replaced text into a buffer at workloc, now * move it to the right place and adjust the stack. */ - startp = stackblock() + startloc; STPUTC('\0', expdest); - memmove(startp, stackblock() + workloc, len); - startp[len++] = '\0'; - amount = expdest - ((char *)stackblock() + startloc + len - 1); + startp = (char *)stackblock() + startloc; + memmove(startp, (char *)stackblock() + workloc, len + 1); + amount = expdest - (startp + len); STADJUST(-amount, expdest); return startp; } @@ -6685,7 +6691,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) */ STPUTC('\0', expdest); patloc = expdest - (char *)stackblock(); - if (0 == subevalvar(p, /* str: */ NULL, patloc, subtype, + if (NULL == subevalvar(p, /* str: */ NULL, patloc, subtype, startloc, varflags, //TODO: | EXP_REDIR too? All other such places do it too /* quotes: */ flags & (EXP_FULL | EXP_CASE), @@ -6848,13 +6854,11 @@ addfname(const char *name) exparg.lastp = &sp->next; } -static char *expdir; - /* * Do metacharacter (i.e. *, ?, [...]) expansion. */ static void -expmeta(char *enddir, char *name) +expmeta(char *expdir, char *enddir, char *name) { char *p; const char *cp; @@ -6953,7 +6957,7 @@ expmeta(char *enddir, char *name) for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';) continue; p[-1] = '/'; - expmeta(p, endname); + expmeta(expdir, p, endname); } } } @@ -7035,6 +7039,7 @@ expandmeta(struct strlist *str /*, int flag*/) /* TODO - EXP_REDIR */ while (str) { + char *expdir; struct strlist **savelastp; struct strlist *sp; char *p; @@ -7051,8 +7056,7 @@ expandmeta(struct strlist *str /*, int flag*/) int i = strlen(str->text); expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */ } - - expmeta(expdir, p); + expmeta(expdir, expdir, p); free(expdir); if (p != str->text) free(p); @@ -9101,19 +9105,15 @@ evalcommand(union node *cmd, int flags) /* Print the command if xflag is set. */ if (xflag) { int n; - const char *p = " %s"; + const char *p = " %s" + 1; - p++; fdprintf(preverrout_fd, p, expandstr(ps4val())); - sp = varlist.list; for (n = 0; n < 2; n++) { while (sp) { fdprintf(preverrout_fd, p, sp->text); sp = sp->next; - if (*p == '%') { - p--; - } + p = " %s"; } sp = arglist.list; } diff --git a/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.right b/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.right new file mode 100644 index 000000000..b212c246c --- /dev/null +++ b/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.right @@ -0,0 +1,10 @@ +192\.168\.0\.1 +192\.168\.0\.1[ +192\.168\.0\.1[ +192\\.168\\.0\\.1[ +192\.168\.0\.1[ +192\.168\.0\.1 +192\.168\.0\.1[ +192\.168\.0\.1[ +192\\.168\\.0\\.1[ +192\.168\.0\.1[ diff --git a/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.tests b/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.tests new file mode 100755 index 000000000..3fa2f186d --- /dev/null +++ b/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.tests @@ -0,0 +1,21 @@ +# The bug here was triggered by: +# * performin pathname expansion because we see [ +# * replace operator did not escape \ in replace string + +IP=192.168.0.1 + +rm -f '192.168.0.1[' +echo "${IP//./\\.}" +echo "${IP//./\\.}"'[' # bug was here +echo "${IP//./\\.}[" # bug was here +echo "${IP//./\\\\.}[" # bug was here +echo "192\.168\.0\.1[" + +echo >'192.168.0.1[' +echo "${IP//./\\.}" +echo "${IP//./\\.}"'[' # bug was here +echo "${IP//./\\.}[" # bug was here +echo "${IP//./\\\\.}[" # bug was here +echo "192\.168\.0\.1[" + +rm -f '192.168.0.1[' -- cgit v1.2.3-55-g6feb