diff --git a/src/ezstream.c b/src/ezstream.c index e11d806..1e875a1 100644 --- a/src/ezstream.c +++ b/src/ezstream.c @@ -116,22 +116,22 @@ _build_reencode_cmd(const char *extension, const char *filename, } tmp = util_utf82char(mdata_get_artist(md)); - artist = util_shellquote(tmp); + artist = util_shellquote(tmp, 0); xfree(tmp); tmp = util_utf82char(mdata_get_album(md)); - album = util_shellquote(tmp); + album = util_shellquote(tmp, 0); xfree(tmp); tmp = util_utf82char(mdata_get_title(md)); - title = util_shellquote(tmp); + title = util_shellquote(tmp, 0); xfree(tmp); tmp = util_utf82char(mdata_get_songinfo(md)); - songinfo = util_shellquote(tmp); + songinfo = util_shellquote(tmp, 0); xfree(tmp); - filename_quoted = util_shellquote(filename); + filename_quoted = util_shellquote(filename, 0); /* * if (prog && format) @@ -150,7 +150,7 @@ _build_reencode_cmd(const char *extension, const char *filename, mdata_strformat(md, buf, sizeof(buf), cfg_get_metadata_format_str()); unquoted = util_utf82char(buf); - custom_songinfo = util_shellquote(unquoted); + custom_songinfo = util_shellquote(unquoted, 0); xfree(unquoted); } else { if (!cfg_get_metadata_program() && diff --git a/src/util.c b/src/util.c index c4aba9a..e0affd9 100644 --- a/src/util.c +++ b/src/util.c @@ -295,19 +295,20 @@ util_expand_words(const char *in, struct util_dict dicts[]) return (out); } -#define SHELLQUOTE_INLEN_MAX 8191UL +#define SHELLQUOTE_OUTLEN_MAX 8191UL char * -util_shellquote(const char *in) +util_shellquote(const char *in, size_t outlen_max) { char *out, *out_p; - size_t out_len; + ssize_t out_len; + size_t out_siz; const char *in_p; - out_len = (strlen(in) > SHELLQUOTE_INLEN_MAX) - ? SHELLQUOTE_INLEN_MAX - : strlen(in); - out_len = out_len * 2 + 2; + if (!outlen_max || outlen_max > SHELLQUOTE_OUTLEN_MAX) + outlen_max = SHELLQUOTE_OUTLEN_MAX; + out_len = outlen_max; + out = xcalloc(out_len + 1, sizeof(char)); out_p = out; @@ -315,16 +316,24 @@ util_shellquote(const char *in) *out_p++ = '\''; out_len--; - while (*in_p && out_len > 2) { + while (*in_p && 1 < out_len) { + int stop = 0; + switch (*in_p) { case '\'': - case '\\': - *out_p++ = '\\'; - out_len--; + if (out_len > 4) { + *out_p++ = '\''; + *out_p++ = '\\'; + *out_p++ = '\''; + out_len -= 3; + } else + stop = 1; break; default: break; } + if (stop) + break; *out_p++ = *in_p++; out_len--; } diff --git a/src/util.h b/src/util.h index 27a0722..9daee56 100644 --- a/src/util.h +++ b/src/util.h @@ -27,7 +27,7 @@ int util_strrcasecmp(const char *, const char *); char * util_char2utf8(const char *); char * util_utf82char(const char *); char * util_expand_words(const char *, struct util_dict[]); -char * util_shellquote(const char *); +char * util_shellquote(const char *, size_t); int util_urlparse(const char *, char **, unsigned short *, char **); #endif /* __UTIL_H__ */