]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
intl: Fix a memory leak.
authorBruno Haible <bruno@clisp.org>
Tue, 15 Oct 2024 19:52:30 +0000 (21:52 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 15 Oct 2024 19:52:30 +0000 (21:52 +0200)
* gettext-runtime/intl/finddomain.c (_nl_find_domain): If there was an alias and
_nl_explode_name or _nl_make_l10nflist fails, free the allocated memory. Avoid
'goto'.

gettext-runtime/intl/finddomain.c

index 123189cad4be1e5a9c2d9ff28ebb62927f484510..23390c5f48f9883b82861bd9a7fa50faf1c34345 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle list of needed message catalogs
-   Copyright (C) 1995-2023 Free Software Foundation, Inc.
+   Copyright (C) 1995-2024 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@gnu.org>, 1995.
 
    This program is free software: you can redistribute it and/or modify
@@ -151,55 +151,52 @@ _nl_find_domain (const char *dirname,
      look for the language.  Termination symbols are `_', '.', and `@'.  */
   mask = _nl_explode_name (locale, &language, &modifier, &territory,
                           &codeset, &normalized_codeset);
-  if (mask == -1)
-    /* This means we are out of core.  */
-    return NULL;
-
-  /* We need to protect modifying the _NL_LOADED_DOMAINS data.  */
-  gl_rwlock_wrlock (lock);
-
-  /* Create all possible locale entries which might be interested in
-     generalization.  */
-  retval = _nl_make_l10nflist (&_nl_loaded_domains,
-                              dirname,
-                              dirname != NULL ? strlen (dirname) + 1 : 0,
+  if (mask != -1) /* not out-of-memory? */
+    {
+      /* We need to protect modifying the _NL_LOADED_DOMAINS data.  */
+      gl_rwlock_wrlock (lock);
+
+      /* Create all possible locale entries which might be interested in
+         generalization.  */
+      retval = _nl_make_l10nflist (&_nl_loaded_domains,
+                                  dirname,
+                                  dirname != NULL ? strlen (dirname) + 1 : 0,
 #if defined _WIN32 && !defined __CYGWIN__
-                              wdirname,
-                              wdirname != NULL ? wcslen (wdirname) + 1 : 0,
+                                  wdirname,
+                                  wdirname != NULL ? wcslen (wdirname) + 1 : 0,
 #endif
-                              mask, language, territory,
-                              codeset, normalized_codeset, modifier,
-                              domainname, 1);
-
-  gl_rwlock_unlock (lock);
+                                  mask, language, territory,
+                                  codeset, normalized_codeset, modifier,
+                                  domainname, 1);
 
-  if (retval == NULL)
-    /* This means we are out of core.  */
-    goto out;
+      gl_rwlock_unlock (lock);
 
-  if (retval->decided <= 0)
-    _nl_load_domain (retval, domainbinding);
-  if (retval->data == NULL)
-    {
-      int cnt;
-      for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
+      if (retval != NULL) /* not out-of-memory? */
        {
-         if (retval->successor[cnt]->decided <= 0)
-           _nl_load_domain (retval->successor[cnt], domainbinding);
-         if (retval->successor[cnt]->data != NULL)
-           break;
+         if (retval->decided <= 0)
+           _nl_load_domain (retval, domainbinding);
+         if (retval->data == NULL)
+           {
+             int cnt;
+             for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
+               {
+                 if (retval->successor[cnt]->decided <= 0)
+                   _nl_load_domain (retval->successor[cnt], domainbinding);
+                 if (retval->successor[cnt]->data != NULL)
+                   break;
+               }
+           }
        }
+
+      /* The space for normalized_codeset is dynamically allocated.  Free it.  */
+      if (mask & XPG_NORM_CODESET)
+        free ((void *) normalized_codeset);
     }
 
   /* The room for an alias was dynamically allocated.  Free it now.  */
   if (alias_value != NULL)
     free (locale);
 
-out:
-  /* The space for normalized_codeset is dynamically allocated.  Free it.  */
-  if (mask & XPG_NORM_CODESET)
-    free ((void *) normalized_codeset);
-
   return retval;
 }