Re: [PATCH perf/core v2 4/8] perf: Make alias handler to check return value of strbuf
From: Arnaldo Carvalho de Melo
Date: Thu May 05 2016 - 19:53:48 EST
Em Sat, Apr 30, 2016 at 12:10:23AM +0900, Masami Hiramatsu escreveu:
> Make alias handler and sq_quote_argv to check the return
> value of strbuf APIs.
> In sq_quote_argv() calls die(), but this fix handles strbuf
> failure as a special case and returns to caller, since
> the caller - handle_alias() also has to check the return
> value of other strbuf APIs and those checks can be merged
> to one if() statement.
Fair enough, looks ok.
> Signed-off-by: Masami Hiramatsu <mhiramat@xxxxxxxxxx>
> ---
> tools/perf/perf.c | 8 +++++---
> tools/perf/util/quote.c | 36 ++++++++++++++++++++----------------
> tools/perf/util/quote.h | 2 +-
> 3 files changed, 26 insertions(+), 20 deletions(-)
>
> diff --git a/tools/perf/perf.c b/tools/perf/perf.c
> index 83ffe7c..7970008 100644
> --- a/tools/perf/perf.c
> +++ b/tools/perf/perf.c
> @@ -309,9 +309,11 @@ static int handle_alias(int *argcp, const char ***argv)
> if (*argcp > 1) {
> struct strbuf buf;
>
> - strbuf_init(&buf, PATH_MAX);
> - strbuf_addstr(&buf, alias_string);
> - sq_quote_argv(&buf, (*argv) + 1, PATH_MAX);
> + if (strbuf_init(&buf, PATH_MAX) < 0 ||
> + strbuf_addstr(&buf, alias_string) < 0 ||
> + sq_quote_argv(&buf, (*argv) + 1,
> + PATH_MAX) < 0)
> + die("Failed to allocate memory.");
> free(alias_string);
> alias_string = buf.buf;
> }
> diff --git a/tools/perf/util/quote.c b/tools/perf/util/quote.c
> index 01f0324..c6d4ee2 100644
> --- a/tools/perf/util/quote.c
> +++ b/tools/perf/util/quote.c
> @@ -17,38 +17,42 @@ static inline int need_bs_quote(char c)
> return (c == '\'' || c == '!');
> }
>
> -static void sq_quote_buf(struct strbuf *dst, const char *src)
> +static int sq_quote_buf(struct strbuf *dst, const char *src)
> {
> char *to_free = NULL;
> + int ret;
>
> if (dst->buf == src)
> to_free = strbuf_detach(dst, NULL);
>
> - strbuf_addch(dst, '\'');
> - while (*src) {
> + ret = strbuf_addch(dst, '\'');
> + while (!ret && *src) {
> size_t len = strcspn(src, "'!");
> - strbuf_add(dst, src, len);
> + ret = strbuf_add(dst, src, len);
> src += len;
> - while (need_bs_quote(*src)) {
> - strbuf_addstr(dst, "'\\");
> - strbuf_addch(dst, *src++);
> - strbuf_addch(dst, '\'');
> - }
> + while (!ret && need_bs_quote(*src))
> + ret = strbuf_addf(dst, "'\\%c\'", *src++);
> }
> - strbuf_addch(dst, '\'');
> + if (!ret)
> + ret = strbuf_addch(dst, '\'');
> free(to_free);
> +
> + return ret;
> }
>
> -void sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen)
> +int sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen)
> {
> - int i;
> + int i, ret;
>
> /* Copy into destination buffer. */
> - strbuf_grow(dst, 255);
> - for (i = 0; argv[i]; ++i) {
> - strbuf_addch(dst, ' ');
> - sq_quote_buf(dst, argv[i]);
> + ret = strbuf_grow(dst, 255);
> + for (i = 0; !ret && argv[i]; ++i) {
> + ret = strbuf_addch(dst, ' ');
> + if (ret)
> + break;
> + ret = sq_quote_buf(dst, argv[i]);
> if (maxlen && dst->len > maxlen)
> die("Too many or long arguments");
> }
> + return ret;
> }
> diff --git a/tools/perf/util/quote.h b/tools/perf/util/quote.h
> index 3340c9c..e1ec191 100644
> --- a/tools/perf/util/quote.h
> +++ b/tools/perf/util/quote.h
> @@ -24,6 +24,6 @@
> * sq_quote() in a real application.
> */
>
> -void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
> +int sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
>
> #endif /* __PERF_QUOTE_H */