bash-3.2.0(1)-release built on a system without native asprintf:
$ printf %x\\n 0x80000000
-80000000

%x is an unsigned format specifier; printing it as signed is bogus. I
tracked the problem down to the implementation of vsnprintf_internal
which bash uses to implement asprintf if it's not present. This
function is buggy and apparently not well-tested. A much saner, less
bloated, bugfree implementation of vasprintf is as follows:

int
vasprintf(char **stringp, const char *format, va_list args)
{
  int l = vsnprintf(NULL, 0, format, args);
  if (l<0) return l;
  *stringp = xmalloc(l+1);
  if (!*stringp) return -1;
  if ((l=vsnprintf(*stringp, l+1, format, args)) < 0) {
    free(*stringp);
    *stringp = 0;
    return l;
  }
  return l;
}

This works (and is free of integer overflows) as long as the host
implementation of vsnprintf is conformant; if vsnprintf is broken
you'll be needing to replace snprintf anyway, but hopefully doing it
with a correct implementation instead of the one that's currently
included with bash.

Rich


Reply via email to