[PATCH 04/14] util/error: allow non-NUL-terminated err->src

Paolo Bonzini posted 14 patches 5 months, 2 weeks ago
[PATCH 04/14] util/error: allow non-NUL-terminated err->src
Posted by Paolo Bonzini 5 months, 2 weeks ago
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.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qapi/error-internal.h | 1 +
 util/error.c                  | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/qapi/error-internal.h b/include/qapi/error-internal.h
index d5c3904adec..f5eb8ad2379 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;
+    int src_len;
     int line;
     GString *hint;
 };
diff --git a/util/error.c b/util/error.c
index e5bcb7c0225..3449ecc0b92 100644
--- a/util/error.c
+++ b/util/error.c
@@ -24,8 +24,8 @@ Error *error_warn;
 static void error_handle(Error **errp, Error *err)
 {
     if (errp == &error_abort) {
-        fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
-                err->func, err->src, err->line);
+        fprintf(stderr, "Unexpected error in %s() at %.*s:%d:\n",
+                err->func, err->src_len, err->src, err->line);
         error_report("%s", error_get_pretty(err));
         if (err->hint) {
             error_printf("%s", err->hint->str);
@@ -67,6 +67,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;
-- 
2.49.0
Re: [PATCH 04/14] util/error: allow non-NUL-terminated err->src
Posted by Markus Armbruster 5 months, 2 weeks ago
Paolo Bonzini <pbonzini@redhat.com> 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.

Stale paragraph :)

> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qapi/error-internal.h | 1 +
>  util/error.c                  | 5 +++--
>  2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/include/qapi/error-internal.h b/include/qapi/error-internal.h
> index d5c3904adec..f5eb8ad2379 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;
> +    int src_len;

In actual usage, we have two cases:

* @src_len is -1 and @src is null-terminated

* @src_len is non-negative and @src is an array of at least that many
  characters, not necessarily null-terminated

This is locally unobvious, and therefore deserves a comment.

Unterminated char * pretty much always deserve one :)

>      int line;
>      GString *hint;
>  };
> diff --git a/util/error.c b/util/error.c
> index e5bcb7c0225..3449ecc0b92 100644
> --- a/util/error.c
> +++ b/util/error.c
> @@ -24,8 +24,8 @@ Error *error_warn;
>  static void error_handle(Error **errp, Error *err)
>  {
>      if (errp == &error_abort) {
> -        fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
> -                err->func, err->src, err->line);
> +        fprintf(stderr, "Unexpected error in %s() at %.*s:%d:\n",
> +                err->func, err->src_len, err->src, err->line);
>          error_report("%s", error_get_pretty(err));
>          if (err->hint) {
>              error_printf("%s", err->hint->str);
> @@ -67,6 +67,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;

This part looks fine to me.