intl: Fix undefined pointer behaviour

In _nl_find_msg (dcigettext.c), outbuf was computed as
freemem + sizeof(size_t) before checking whether freemem_size is
large enough.  When freemem is NULL (initial state), this is
undefined behaviour i.e arithmetic on a null pointer.  Move the
outbuf assignment after the size check where freemem is guaranteed
to be a valid allocation.

In read_alias_file (localealias.c), after realloc the old
string_space pointer is dangling.  The expression
new_pool - string_space subtracts a valid pointer from a dangling
one, which is undefined behaviour per ISO C 23.
Rewrite as new_pool + (map[i].alias - string_space) so both
operands of the subtraction point into the same (old) object
before string_space is reassigned.

Based on GNU gettext commits 695429040 and 2ebbdd0e2.
Original author: Bruno Haible <bruno@clisp.org>

Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
This commit is contained in:
Avinal Kumar
2026-05-20 17:22:03 -03:00
committed by Adhemerval Zanella
parent 209ad6ff9d
commit 8aa4a70431
2 changed files with 10 additions and 11 deletions
+6 -9
View File
@@ -1136,7 +1136,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
@@ -1145,13 +1144,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,
@@ -1177,9 +1179,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,
@@ -1248,8 +1247,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
+4 -2
View File
@@ -329,8 +329,10 @@ read_alias_file (const char *fname, int fname_len)
for (i = 0; i < nmap; i++)
{
map[i].alias += new_pool - string_space;
map[i].value += new_pool - string_space;
map[i].alias =
new_pool + (map[i].alias - string_space);
map[i].value =
new_pool + (map[i].value - string_space);
}
}