On Mon, Apr 13, 2026 at 03:50:24PM +0200, Willy Tarreau wrote:
> Subject: Re: [PATCH] MINOR: errors: remove excessive errmsg checks
> On Mon, Apr 13, 2026 at 02:19:38PM +0200, William Lallemand wrote:
> > On Sat, Apr 11, 2026 at 04:03:43PM +0000, Egor Shestakov wrote:
> > > Subject: [PATCH] MINOR: errors: remove excessive errmsg checks
> > > I noticed some strange checks for presence of errmsg. Called functions
> > > generate non-empty error message in case of failure, so a non-NULL address
> > > of the error message is enough.
> > > 
> > > No backport needed.
> > 
> > I'm not seeing this as excessive, it just avoids emitting a message with an
> > empty string, even if it does not seem useful this is just a guarantee if 
> > the
> > message emission is not done correctly. I don't think it's useful to remove
> > them. Ideally we should probably wrap the error generation in some function
> > which would that itself everywhere... But that's another story.
> 
> In fact that was not the goal of these tests, it the result of a messed
> up copy-paste from the same test appearing everywhere we use *errmsg like
> this:
> 
> @@ -164,6 +188,7 @@ int sockpair_bind_receiver(struct receiver *rx, char 
> **errmsg)
>         if (errmsg && *errmsg)
>                 memprintf(errmsg, "%s for [fd %d]", *errmsg, rx->fd);
>  
> And by mimetism these check have slipped everywhere a char * is used
> instead of a char **. Take sockpair_bind_receiver() for example:
> 
>   int sockpair_bind_receiver(struct receiver *rx, char **errmsg)
>   {
> 
>         if (rx->fd == -1) {
>                 err |= ERR_FATAL | ERR_ALERT;
>                 memprintf(errmsg, "sockpair may be only used with inherited 
> FDs");
>                 goto bind_return;
>         }
>         (...)
> 
>    bind_return:
>         if (errmsg && *errmsg)
>                 memprintf(errmsg, "%s for [fd %d]", *errmsg, rx->fd);
> 
> See ? It's impossible here to get errmsg && !*errmsg because of the
> way we arrive there (memprintf() already used to fill the message).
> 
> There remain other places like this with variants such as testing
> for (errmsg && *errmsg) before calling indent_msg() after having
> already filled errmsg() from memprintf().
> 
> Overall I think these are not important, and that we'll continue to
> regularly mess up with them because half of the "errmsg" are pointers
> to strings while the other half are strings, yet the condition remains
> the same...
>  
> > > diff --git a/src/acme.c b/src/acme.c
> > > index eb7137b4c..437528c08 100644
> > > --- a/src/acme.c
> > > +++ b/src/acme.c
> > > @@ -800,8 +800,8 @@ static int cfg_postsection_acme()
> > >   /* tries to open the account key  */
> > >   if (stat(path, &st) == 0) {
> > >           if (ssl_sock_load_key_into_ckch(path, NULL, store->data, 
> > > &errmsg)) {
> > > -                 memprintf(&errmsg, "%s'%s' is present but cannot be 
> > > read or parsed.\n", errmsg && *errmsg ? errmsg : NULL, path);
> > > -                 if (errmsg && *errmsg)
> > > +                 memprintf(&errmsg, "%s'%s' is present but cannot be 
> > > read or parsed.\n", errmsg, path);
> > > +                 if (errmsg)
> > >                           indent_msg(&errmsg, 8);
> > >                   err_code |= ERR_ALERT | ERR_FATAL | ERR_ABORT;
> > >                   ha_alert("acme: %s\n", errmsg);
> > 
> > In my opinion this first part should be in a separate BUG/MINOR patch which
> > should be backported.
> 
> Sorry, too late, I just merged it :-( I can revert it and re-apply
> it as a separate fix if needed, though it's not really important as
> most of the time it will just print "(null)" for empty messages
> instead of nothing, though I'm not aware of any command not emitting
> empty error messages.
> 

I misread this particular part, I thought it introduced the check, so that's
fine.

-- 
William Lallemand


Reply via email to