From a47247a948e47f6bbadcf15f031af902d1f42551 Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Thu, 29 Jul 2010 08:17:36 +0200 Subject: fixed pl_format_title code duplication in shellexec plugin --- plugins/shellexec/shellexec.c | 116 ++++-------------------------------------- 1 file changed, 9 insertions(+), 107 deletions(-) (limited to 'plugins/shellexec') diff --git a/plugins/shellexec/shellexec.c b/plugins/shellexec/shellexec.c index 7e65c52a..84a77bad 100644 --- a/plugins/shellexec/shellexec.c +++ b/plugins/shellexec/shellexec.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "../../deadbeef.h" @@ -82,117 +83,18 @@ trim (char* s) return h; } -static int -shell_quote (const char *source, char *dest) -{ - const char *sp; - char *dp; - - for (sp = source, dp = dest; *sp; sp++, dp++) - { - if (*sp == '\'') - { - strcpy (dp, "'\\''"); - dp += 3; - } - else - *dp = *sp; - } - *dp = 0; -} - - -/* - format_shell_command function - Similarly to db_format_title formats track's string - and quotes all fields to make them safe for shell - - %a, %t, %b, %B, %C, %n, %N, %y, %g, %c, %r are handled. Use double-% to - skip field. - - - Example: - - Format string: - echo %a - %t %%a - %%t - - Output: - echo 'Blind Faith' - 'Can'\''t Find My Way Home' %a - %t -*/ -static char* -format_shell_command (DB_playItem_t *it, const char *format) -{ - char *p; - const char *trailing = format; - const char *field; - char *res, *res_p; - - res = res_p = malloc (65536); //FIXME: possible heap corruption - - for (;;) - { - p = strchr (trailing, '%'); - if (!p) break; - - switch (*(p+1)) - { - case 'a': field = "artist"; break; - case 't': field = "title"; break; - case 'b': field = "album"; break; - case 'B': field = "band"; break; - case 'C': field = "composer"; break; - case 'n': field = "track"; break; - case 'N': field = "numtracks"; break; - case 'y': field = "year"; break; - case 'g': field = "genre"; break; - case 'c': field = "comment"; break; - case 'r': field = "copyright"; break; - case 'f': break; - default: field = NULL; - } - - if (field == NULL) - { - int l = ((*(p+1) == '%') ? 1 : 0); - trace ("field is null; p: %s; p+1: %s; l: %d; trailing: %s; res_p: %s\n", p, p+1, l, trailing, res_p); - strncpy (res_p, trailing, p-trailing+l); - res_p += (p-trailing+l); - trailing = p+l+1; - trace ("res: %s; trailing: %s\n", res, res_p, trailing); - continue; - } - else - { - const char *meta; - if (*(p+1) == 'f') - meta = it->fname; - else - meta = deadbeef->pl_find_meta (it, field); - - char quoted [strlen (meta) * 4 + 1]; //Worst case is when all chars are single quote - shell_quote (meta, quoted); - - strncpy (res_p, trailing, p-trailing); - res_p += (p-trailing); - *res_p++ = '\''; - strcpy (res_p, quoted); - res_p += strlen (quoted); - *res_p++ = '\''; - trailing = p+2; - } - } - strcpy (res_p, trailing); - strcat (res_p, "&"); - return res; -} - static int shx_callback (Shx_action_t *action, DB_playItem_t *it) { - char *cmd = format_shell_command (it, action->shcommand); - printf ("%s\n", cmd); + char cmd[_POSIX_ARG_MAX]; + int res = deadbeef->pl_format_title_escaped (it, -1, cmd, sizeof (cmd) - 2, -1, action->shcommand); + if (res < 0) { + trace ("shellexec: failed to format string for execution (too long?)\n"); + return -1; + } + strcat (cmd, "&"); + trace ("%s\n", cmd); system (cmd); - free (cmd); return 0; } -- cgit v1.2.3