Paolo Bonzini <[email protected]> writes:

> Rust makes the current file available as a statically-allocated string,
> but without a NUL terminator.  Allow this by storing an optional maximum
> length in the Error.
>
> Note that for portability I am not relying on fprintf's precision
> specifier not accessing memory beyond what will be printed.

Can you elaborate on the portability problem?  I figure ...

> Signed-off-by: Paolo Bonzini <[email protected]>
> ---
>  include/qapi/error-internal.h | 1 +
>  util/error.c                  | 8 +++++++-
>  2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/include/qapi/error-internal.h b/include/qapi/error-internal.h
> index d5c3904adec..6178ce4a63d 100644
> --- a/include/qapi/error-internal.h
> +++ b/include/qapi/error-internal.h
> @@ -19,6 +19,7 @@ struct Error
>      char *msg;
>      ErrorClass err_class;
>      const char *src, *func;
> +    ssize_t src_len;
>      int line;
>      GString *hint;
>  };
> diff --git a/util/error.c b/util/error.c
> index e5bcb7c0225..6c1033eaba5 100644
> --- a/util/error.c
> +++ b/util/error.c
> @@ -24,8 +24,13 @@ Error *error_warn;
>  static void error_handle(Error **errp, Error *err)
>  {
>      if (errp == &error_abort) {
> +        const char *src = err->src;
> +        if (err->src_len >= 0) {
> +            /* No need to free it, the program will abort very soon...  */
> +            src = g_strndup(err->src, err->src_len);
> +        }
>          fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
> -                err->func, err->src, err->line);
> +                err->func, src, err->line);

... you're avoiding the simpler

           fprintf(stderr, "Unexpected error in %s() at %.*s:%d:\n",
                   err->func, err->src_len, err->src, err->line);

because of it.

(@src_len needs to be int then, and its default value below INT_MAX)

>          error_report("%s", error_get_pretty(err));
>          if (err->hint) {
>              error_printf("%s", err->hint->str);
> @@ -67,6 +72,7 @@ static void error_setv(Error **errp,
>          g_free(msg);
>      }
>      err->err_class = err_class;
> +    err->src_len = -1;
>      err->src = src;
>      err->line = line;
>      err->func = func;


Reply via email to