diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-17 09:17:51 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-17 09:17:51 +0000 |
| commit | 0f683f818cf087d580ba2edf7c096897bc28b95a (patch) | |
| tree | 0324365d1cf7ec43679c202681fe55bfa81e439f /coreutils | |
| parent | 416914fc6115d2013433a5956febcffb5c8a0466 (diff) | |
| download | busybox-w32-0f683f818cf087d580ba2edf7c096897bc28b95a.tar.gz busybox-w32-0f683f818cf087d580ba2edf7c096897bc28b95a.tar.bz2 busybox-w32-0f683f818cf087d580ba2edf7c096897bc28b95a.zip | |
printf: protect against bogus format specifiers. Hopefully closes bug 4184
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/printf.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c index a14306f5a..d877e0581 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c | |||
| @@ -33,7 +33,8 @@ | |||
| 33 | The 'format' argument is re-used as many times as necessary | 33 | The 'format' argument is re-used as many times as necessary |
| 34 | to convert all of the given arguments. | 34 | to convert all of the given arguments. |
| 35 | 35 | ||
| 36 | David MacKenzie <djm@gnu.ai.mit.edu> */ | 36 | David MacKenzie <djm@gnu.ai.mit.edu> |
| 37 | */ | ||
| 37 | 38 | ||
| 38 | 39 | ||
| 39 | // 19990508 Busy Boxed! Dave Cinege | 40 | // 19990508 Busy Boxed! Dave Cinege |
| @@ -251,10 +252,12 @@ static char **print_formatted(char *f, char **argv) | |||
| 251 | ++f; | 252 | ++f; |
| 252 | ++direc_length; | 253 | ++direc_length; |
| 253 | } | 254 | } |
| 254 | /* | 255 | /* needed - try "printf %" without it */ |
| 255 | if (!strchr ("diouxXfeEgGcs", *f)) | 256 | if (!strchr("diouxXfeEgGcs", *f)) { |
| 256 | fprintf(stderr, "%%%c: invalid directive", *f); | 257 | bb_error_msg("invalid directive '%s'", direc_start); |
| 257 | */ | 258 | /* causes main() to exit with error */ |
| 259 | return saved_argv - 1; | ||
| 260 | } | ||
| 258 | ++direc_length; | 261 | ++direc_length; |
| 259 | if (*argv) { | 262 | if (*argv) { |
| 260 | print_direc(direc_start, direc_length, field_width, | 263 | print_direc(direc_start, direc_length, field_width, |
| @@ -285,7 +288,8 @@ int printf_main(int argc UNUSED_PARAM, char **argv) | |||
| 285 | char **argv2; | 288 | char **argv2; |
| 286 | 289 | ||
| 287 | /* We must check that stdout is not closed. | 290 | /* We must check that stdout is not closed. |
| 288 | * The reason for this is highly non-obvious. printf_main is used from shell. | 291 | * The reason for this is highly non-obvious. |
| 292 | * printf_main is used from shell. | ||
| 289 | * Shell must correctly handle 'printf "%s" foo' | 293 | * Shell must correctly handle 'printf "%s" foo' |
| 290 | * if stdout is closed. With stdio, output gets shoveled into | 294 | * if stdout is closed. With stdio, output gets shoveled into |
| 291 | * stdout buffer, and even fflush cannot clear it out. It seems that | 295 | * stdout buffer, and even fflush cannot clear it out. It seems that |
| @@ -298,7 +302,7 @@ int printf_main(int argc UNUSED_PARAM, char **argv) | |||
| 298 | /* bash builtin errors out on "printf '-%s-\n' foo", | 302 | /* bash builtin errors out on "printf '-%s-\n' foo", |
| 299 | * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo". | 303 | * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo". |
| 300 | * We will mimic coreutils. */ | 304 | * We will mimic coreutils. */ |
| 301 | if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && argv[1][2] == '\0') | 305 | if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && !argv[1][2]) |
| 302 | argv++; | 306 | argv++; |
| 303 | if (!argv[1]) | 307 | if (!argv[1]) |
| 304 | bb_show_usage(); | 308 | bb_show_usage(); |
| @@ -309,12 +313,12 @@ int printf_main(int argc UNUSED_PARAM, char **argv) | |||
| 309 | do { | 313 | do { |
| 310 | argv = argv2; | 314 | argv = argv2; |
| 311 | argv2 = print_formatted(format, argv); | 315 | argv2 = print_formatted(format, argv); |
| 312 | } while (argv2 != argv && *argv2); | 316 | } while (argv2 > argv && *argv2); |
| 313 | 317 | ||
| 314 | /* coreutils compat (bash doesn't do this): | 318 | /* coreutils compat (bash doesn't do this): |
| 315 | if (*argv) | 319 | if (*argv) |
| 316 | fprintf(stderr, "excess args ignored"); | 320 | fprintf(stderr, "excess args ignored"); |
| 317 | */ | 321 | */ |
| 318 | 322 | ||
| 319 | return EXIT_SUCCESS; | 323 | return (argv2 < argv); /* if true, print_formatted errored out */ |
| 320 | } | 324 | } |
