]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
intl: Fix undefined behaviour.
authorBruno Haible <bruno@clisp.org>
Wed, 29 Jan 2025 11:30:02 +0000 (12:30 +0100)
committerBruno Haible <bruno@clisp.org>
Wed, 29 Jan 2025 11:30:02 +0000 (12:30 +0100)
Found using clang's undefined-behaviour sanitizer:
CC="clang -fsanitize=undefined -fno-sanitize-recover=undefined".
It reported errors
dcigettext.c:1219:25: runtime error: applying non-zero offset 8 to null pointer
because the code was computing
    outbuf = freemem + sizeof (size_t);
where freemem == NULL.

* gettext-runtime/intl/dcigettext.c (_nl_find_msg): Initialize outbuf only after
having verified that freemem_size >= sizeof (size_t).

gettext-runtime/intl/dcigettext.c

index 3a63294735be7f5c3e9929cb2944b7dc62008f82..899a487b53356c7313ea948fc05894301ab14e68 100644 (file)
@@ -1,5 +1,5 @@
 /* Implementation of the internal dcigettext function.
-   Copyright (C) 1995-2024 Free Software Foundation, Inc.
+   Copyright (C) 1995-2025 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
@@ -1216,7 +1216,6 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
            not_translated_yet:
 
              inbuf = (const unsigned char *) result;
-             outbuf = freemem + sizeof (size_t);
 # ifndef _LIBC
              transmem_list = NULL;
 # endif
@@ -1225,13 +1224,16 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
              while (1)
                {
                  transmem_block_t *newmem;
-# ifdef _LIBC
-                 size_t non_reversible;
-                 int res;
 
                  if (freemem_size < sizeof (size_t))
                    goto resize_freemem;
 
+                 outbuf = freemem + sizeof (size_t);
+
+# ifdef _LIBC
+                 size_t non_reversible;
+                 int res;
+
                  res = __gconv (convd->conv,
                                 &inbuf, inbuf + resultlen,
                                 &outbuf,
@@ -1257,9 +1259,6 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
                  char *outptr = (char *) outbuf;
                  size_t outleft;
 
-                 if (freemem_size < sizeof (size_t))
-                   goto resize_freemem;
-
                  outleft = freemem_size - sizeof (size_t);
                  if (iconv (convd->conv,
                             (ICONV_CONST char **) &inptr, &inleft,
@@ -1328,8 +1327,6 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
                  transmem_list = newmem;
                  freemem = newmem;
 # endif
-
-                 outbuf = freemem + sizeof (size_t);
                }
 
              /* We have now in our buffer a converted string.  Put this