aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-03 00:07:05 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-03 00:07:05 +0000
commitf9f74293465e98f2af117a1821a8fbb97cdbc3ed (patch)
tree5a696966b90b08535a6d1f581357aeb65dfdbeb0
parent027e3fddb580bf3b397f2392b7e6aeab69adac79 (diff)
downloadbusybox-w32-f9f74293465e98f2af117a1821a8fbb97cdbc3ed.tar.gz
busybox-w32-f9f74293465e98f2af117a1821a8fbb97cdbc3ed.tar.bz2
busybox-w32-f9f74293465e98f2af117a1821a8fbb97cdbc3ed.zip
hush: explain parsing context structure
plug leak in setup_redirect on error path function old new delta done_command 84 86 +2 done_word 657 658 +1 done_pipe 105 106 +1 initialize_context 39 38 -1 setup_redirect 219 212 -7 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/2 up/down: 4/-8) Total: -4 bytes
-rw-r--r--shell/hush.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/shell/hush.c b/shell/hush.c
index eeec13b3d..d401948aa 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -359,9 +359,13 @@ struct pipe {
359 359
360/* This holds pointers to the various results of parsing */ 360/* This holds pointers to the various results of parsing */
361struct parse_context { 361struct parse_context {
362 struct command *command; 362 /* linked list of pipes */
363 struct pipe *list_head; 363 struct pipe *list_head;
364 /* last pipe (being constructed right now) */
364 struct pipe *pipe; 365 struct pipe *pipe;
366 /* last command in pipe (being constructed right now) */
367 struct command *command;
368 /* last redirect in command->redirects list */
365 struct redir_struct *pending_redirect; 369 struct redir_struct *pending_redirect;
366#if HAS_KEYWORDS 370#if HAS_KEYWORDS
367 smallint ctx_res_w; 371 smallint ctx_res_w;
@@ -369,7 +373,15 @@ struct parse_context {
369#if ENABLE_HUSH_CASE 373#if ENABLE_HUSH_CASE
370 smallint ctx_dsemicolon; /* ";;" seen */ 374 smallint ctx_dsemicolon; /* ";;" seen */
371#endif 375#endif
372 int old_flag; /* bitmask of FLAG_xxx, for figuring out valid reserved words */ 376 /* bitmask of FLAG_xxx, for figuring out valid reserved words */
377 int old_flag;
378 /* group we are enclosed in:
379 * example 1: "{ { false; ..."
380 * example 2: "if true; then { false; ..."
381 * example 3: "if true; then if false; ..."
382 * when we find closing "}" / "fi" / whatever, we move list_head
383 * into stack->command->group and delete ourself.
384 */
373 struct parse_context *stack; 385 struct parse_context *stack;
374#endif 386#endif
375}; 387};
@@ -3288,37 +3300,36 @@ static int redirect_dup_num(struct in_str *input)
3288 * for file descriptor duplication, e.g., "2>&1". 3300 * for file descriptor duplication, e.g., "2>&1".
3289 * Return code is 0 normally, 1 if a syntax error is detected in src. 3301 * Return code is 0 normally, 1 if a syntax error is detected in src.
3290 * Resource errors (in xmalloc) cause the process to exit */ 3302 * Resource errors (in xmalloc) cause the process to exit */
3291static int setup_redirect(struct parse_context *ctx, int fd, redir_type style, 3303static int setup_redirect(struct parse_context *ctx,
3292 struct in_str *input) 3304 int fd,
3305 redir_type style,
3306 struct in_str *input)
3293{ 3307{
3294 struct command *command = ctx->command; 3308 struct command *command = ctx->command;
3295 struct redir_struct *redir = command->redirects; 3309 struct redir_struct *redir;
3296 struct redir_struct *last_redir = NULL; 3310 struct redir_struct **redirp;
3311 int dup_num;
3312
3313 /* Check for a '2>&1' type redirect */
3314 dup_num = redirect_dup_num(input);
3315 if (dup_num == -2)
3316 return 1; /* syntax error */
3297 3317
3298 /* Create a new redir_struct and drop it onto the end of the linked list */ 3318 /* Create a new redir_struct and drop it onto the end of the linked list */
3299 while (redir) { 3319 redirp = &command->redirects;
3300 last_redir = redir; 3320 while ((redir = *redirp) != NULL) {
3301 redir = redir->next; 3321 redirp = &(redir->next);
3302 } 3322 }
3303 redir = xzalloc(sizeof(struct redir_struct)); 3323 *redirp = redir = xzalloc(sizeof(*redir));
3304 /* redir->next = NULL; */ 3324 /* redir->next = NULL; */
3305 /* redir->rd_filename = NULL; */ 3325 /* redir->rd_filename = NULL; */
3306 if (last_redir) {
3307 last_redir->next = redir;
3308 } else {
3309 command->redirects = redir;
3310 }
3311
3312 redir->rd_type = style; 3326 redir->rd_type = style;
3313 redir->fd = (fd == -1) ? redir_table[style].default_fd : fd; 3327 redir->fd = (fd == -1) ? redir_table[style].default_fd : fd;
3314 3328
3315 debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip); 3329 debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip);
3316 3330
3317 /* Check for a '2>&1' type redirect */ 3331 redir->dup = dup_num;
3318 redir->dup = redirect_dup_num(input); 3332 if (dup_num != -1) {
3319 if (redir->dup == -2)
3320 return 1; /* syntax error */
3321 if (redir->dup != -1) {
3322 /* Erik had a check here that the file descriptor in question 3333 /* Erik had a check here that the file descriptor in question
3323 * is legit; I postpone that to "run time" 3334 * is legit; I postpone that to "run time"
3324 * A "-" representation of "close me" shows up as a -3 here */ 3335 * A "-" representation of "close me" shows up as a -3 here */