[tz] tzcode: uninitialized sp->charcnt gives clang analyzer warning

Guy Harris gharris at sonic.net
Tue Aug 10 17:18:52 UTC 2021

On Aug 10, 2021, at 5:58 AM, Tom Lane <tgl at sss.pgh.pa.us> wrote:

> Guy Harris via tz <tz at iana.org> writes:
>> On Aug 9, 2021, at 3:55 PM, Jan Engelhardt via tz <tz at iana.org> wrote:
>>> tzload then returns errno, which is 0 under these pretenses, thereby signalling
>>> to its caller that everything was fine, when it fact it wasn't.
>> Then it should be fixed not to do so, e.g. by returning ENOMEM if errno is 0.
> I'm not quite sure which part you're saying should be fixed.
> But it's entirely legal per C99 (not POSIX) for malloc not to
> bother setting errno. AFAICS, C99 doesn't even specify the
> existence of ENOMEM.

Then a routine that calls malloc() must not return 0 on success and the value of errno on an error.

Instead, it should do something such as

/* Load tz data from the file named NAME into *SP.  Read extended
   format if DOEXTEND.  Return 0 on success, an errno value on failure.  */
static int
tzload(char const *name, struct state *sp, bool doextend)
#ifdef ALL_STATE
  union local_storage *lsp = malloc(sizeof *lsp);
  if (!lsp) {
    return HAVE_MALLOC_ERRNO ? errno : ENOMEM;
  } else {
    int err = tzloadbody(name, sp, doextend, lsp);
    return err;
  union local_storage ls;
  return tzloadbody(name, sp, doextend, &ls);

which is, in fact, what the tip of the main branch is currently doing.  That ensures that tzload() always returns a non-zero value if malloc() fails, so that its caller can distinguish between "malloc succeeded" and "malloc failed".

See Git commit d9b364304b9f56e7c94252e84829efba3804417b in the tz Git repository for the full change.

More information about the tz mailing list