]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Fix a small memory leak in libgettextpo.
authorBruno Haible <bruno@clisp.org>
Sun, 25 Jan 2026 18:17:48 +0000 (19:17 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 25 Jan 2026 18:17:48 +0000 (19:17 +0100)
Reported by <gemmaro.dev@gmail.com> at
<https://savannah.gnu.org/bugs/index.php?item_id=67892>
and by Albert Astals Cid <aacid@kde.org> in
<https://lists.gnu.org/archive/html/bug-gettext/2026-01/msg00071.html>.

* gettext-tools/src/read-po-lex.h: Include str-list.h.
(lex_start): Add arena parameter.
* gettext-tools/src/read-po-lex.c (lex_start): Add arena parameter. Add the
heap-allocated file_name to the arena.
* gettext-tools/src/read-catalog-abstract.h: Include str-list.h.
(struct catalog_input_format): Add arena parameter to parse() method.
(catalog_reader_parse): Add arena parameter.
* gettext-tools/src/read-properties.c (properties_parse): Add arena parameter.
* gettext-tools/src/read-stringtable.c (stringtable_parse): Add arena parameter.
* gettext-tools/src/read-po.c (po_parse): Add arena parameter. Update lex_start
call.
* gettext-tools/src/read-catalog-abstract.c (catalog_reader_parse): Add arena
parameter. Update parse() method call.
* gettext-tools/src/read-catalog.h: Include str-list.h.
(read_catalog_stream): Add arena parameter.
* gettext-tools/src/read-catalog.c (read_catalog_stream): Add arena parameter.
Update catalog_reader_parse call.
* gettext-tools/src/read-catalog-file.c: Include str-list.h.
(read_catalog_file): Update read_catalog_stream call.
* gettext-tools/src/read-csharp.c: Include str-list.h.
(execute_and_read_po_output): Update read_catalog_stream call.
* gettext-tools/src/read-java.c: Include str-list.h.
(execute_and_read_po_output): Update read_catalog_stream call.
* gettext-tools/src/read-resources.c: Include str-list.h.
(execute_and_read_po_output): Update read_catalog_stream call.
* gettext-tools/src/read-tcl.c: Include str-list.h.
(msgdomain_read_tcl): Update read_catalog_stream call.
* gettext-tools/libgettextpo/gettext-po.c: Include str-list.h.
(struct po_file): Add field 'arena'.
(po_file_create): Initialize it.
(po_file_read): Likewise. Update read_catalog_stream call.
(po_file_free): Destroy the arena.
* gettext-tools/src/msgfmt.c (read_catalog_file_msgfmt): Update
catalog_reader_parse call.
* gettext-tools/src/x-po.c: Include str-list.h.
(extract): Update catalog_reader_parse call.
* gettext-tools/src/xgettext.c (read_exclusion_file): Update
catalog_reader_parse call.

18 files changed:
gettext-tools/libgettextpo/gettext-po.c
gettext-tools/src/msgfmt.c
gettext-tools/src/read-catalog-abstract.c
gettext-tools/src/read-catalog-abstract.h
gettext-tools/src/read-catalog-file.c
gettext-tools/src/read-catalog.c
gettext-tools/src/read-catalog.h
gettext-tools/src/read-csharp.c
gettext-tools/src/read-java.c
gettext-tools/src/read-po-lex.c
gettext-tools/src/read-po-lex.h
gettext-tools/src/read-po.c
gettext-tools/src/read-properties.c
gettext-tools/src/read-resources.c
gettext-tools/src/read-stringtable.c
gettext-tools/src/read-tcl.c
gettext-tools/src/x-po.c
gettext-tools/src/xgettext.c

index 5fbb00c7cd99ece85e333327f74feb84a21151e7..bff373b2fc8acd7b4b745f178435ae25dd7e5077 100644 (file)
@@ -1,5 +1,5 @@
 /* Public API for GNU gettext PO files.
-   Copyright (C) 2003-2025 Free Software Foundation, Inc.
+   Copyright (C) 2003-2026 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -26,6 +26,7 @@
 #include <string.h>
 
 #include "message.h"
+#include "str-list.h"
 #include "xalloc.h"
 #include "read-catalog.h"
 #include "read-po.h"
@@ -45,6 +46,9 @@ struct po_file
   const char *real_filename;
   const char *logical_filename;
   const char **domains;
+  /* Heap allocations that are guaranteed to persist until the po_file_free
+     call.  */
+  string_list_ty arena;
 };
 
 struct po_message_iterator
@@ -83,6 +87,7 @@ po_file_create (void)
   file->real_filename = _("<unnamed>");
   file->logical_filename = file->real_filename;
   file->domains = NULL;
+  string_list_init (&file->arena);
   return file;
 }
 
@@ -122,9 +127,10 @@ po_file_read (const char *filename, po_xerror_handler_t handler)
   file = XMALLOC (struct po_file);
   file->real_filename = filename;
   file->logical_filename = filename;
+  string_list_init (&file->arena);
   file->mdlp = read_catalog_stream (fp, file->real_filename,
                                     file->logical_filename, &input_format_po,
-                                    &local_xerror_handler);
+                                    &local_xerror_handler, &file->arena);
   file->domains = NULL;
 
   if (fp != stdin)
@@ -165,6 +171,7 @@ po_file_free (po_file_t file)
   msgdomain_list_free (file->mdlp);
   if (file->domains != NULL)
     free (file->domains);
+  string_list_destroy (&file->arena);
   free (file);
 }
 
index 2f3f95013f26975261308e4b0609c954684e5444..eb4888ce4158019c77ceb2ca60bfca6defcca9f8 100644 (file)
@@ -1437,8 +1437,10 @@ read_catalog_file_msgfmt (char *filename, catalog_input_format_ty input_syntax)
       dcatr->mlp = current_domain->mlp;
     }
 
+  string_list_ty arena;
+  string_list_init (&arena);
   catalog_reader_parse ((abstract_catalog_reader_ty *) dcatr, fp, real_filename,
-                        filename, false, input_syntax);
+                        filename, false, input_syntax, &arena);
 
   catalog_reader_free ((abstract_catalog_reader_ty *) dcatr);
 
index d9492cfef3f1a7bc2477281ee142730ed2fa78ee..888ffc9759f35edf87df366accfb583b1165c8a3 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading textual message catalogs (such as PO files), abstract class.
-   Copyright (C) 1995-2025 Free Software Foundation, Inc.
+   Copyright (C) 1995-2026 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
@@ -152,13 +152,15 @@ void
 catalog_reader_parse (abstract_catalog_reader_ty *catr, FILE *fp,
                       const char *real_filename, const char *logical_filename,
                       bool is_pot_role,
-                      catalog_input_format_ty input_syntax)
+                      catalog_input_format_ty input_syntax,
+                      string_list_ty *arena)
 {
   *(catr->xeh->error_message_count_p) = 0;
 
   /* Parse the stream's content.  */
   call_parse_brief (catr);
-  input_syntax->parse (catr, fp, real_filename, logical_filename, is_pot_role);
+  input_syntax->parse (catr, fp, real_filename, logical_filename,
+                       is_pot_role, arena);
   call_parse_debrief (catr);
 
   unsigned int num_errors = *(catr->xeh->error_message_count_p);
index 9112226feab5854538c19c7600baa9770bfec53a..24f92d83d3ba12d50832b4f09a083976be530733 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading textual message catalogs (such as PO files), abstract class.
-   Copyright (C) 1995-2025 Free Software Foundation, Inc.
+   Copyright (C) 1995-2026 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
@@ -24,6 +24,7 @@
 
 #include "message.h"
 #include "xerror-handler.h"
+#include "str-list.h"
 
 
 #ifdef __cplusplus
@@ -158,7 +159,7 @@ struct catalog_input_format
   /* Parses the contents of FP, invoking the appropriate callbacks.  */
   void (*parse) (abstract_catalog_reader_ty *catr, FILE *fp,
                  const char *real_filename, const char *logical_filename,
-                 bool is_pot_role);
+                 bool is_pot_role, string_list_ty *arena);
 
   /* Whether the parse function always produces messages encoded in UTF-8
      encoding.  */
@@ -181,7 +182,8 @@ extern void
                              const char *real_filename,
                              const char *logical_filename,
                              bool is_pot_role,
-                             catalog_input_format_ty input_syntax);
+                             catalog_input_format_ty input_syntax,
+                             string_list_ty *arena);
 
 /* Call the destructor and deallocate a abstract_catalog_reader_ty (or derived
    class) instance.  */
index e6eca5ae6438a7b85e3f426a909bc567c0f197d2..78ecbdeac630a8ae44cb3de543e672a455bc2c79 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading PO files.
-   Copyright (C) 1995-2025 Free Software Foundation, Inc.
+   Copyright (C) 1995-2026 Free Software Foundation, Inc.
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
    This program is free software: you can redistribute it and/or modify
@@ -21,6 +21,7 @@
 #include "read-catalog-file.h"
 
 #include "open-catalog.h"
+#include "str-list.h"
 #include "xerror-handler.h"
 
 
@@ -30,9 +31,11 @@ read_catalog_file (const char *filename, catalog_input_format_ty input_syntax)
   char *real_filename;
   FILE *fp = open_catalog_file (filename, &real_filename, true);
 
+  string_list_ty arena;
+  string_list_init (&arena);
   msgdomain_list_ty *result =
     read_catalog_stream (fp, real_filename, filename, input_syntax,
-                         textmode_xerror_handler);
+                         textmode_xerror_handler, &arena);
 
   if (fp != stdin)
     fclose (fp);
index 186585cb2122aa3db3d86f5b72ac1b8cef0e121e..7926d29691fee635cfdd9d5f4d231ee0b667b993 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading textual message catalogs (such as PO files).
-   Copyright (C) 1995-2025 Free Software Foundation, Inc.
+   Copyright (C) 1995-2026 Free Software Foundation, Inc.
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
    This program is free software: you can redistribute it and/or modify
@@ -481,7 +481,8 @@ msgdomain_list_ty *
 read_catalog_stream (FILE *fp, const char *real_filename,
                      const char *logical_filename,
                      catalog_input_format_ty input_syntax,
-                     xerror_handler_ty xerror_handler)
+                     xerror_handler_ty xerror_handler,
+                     string_list_ty *arena)
 {
   default_catalog_reader_ty *dcatr =
     default_catalog_reader_alloc (&default_methods, xerror_handler);
@@ -498,7 +499,7 @@ read_catalog_stream (FILE *fp, const char *real_filename,
     dcatr->mdlp->encoding = po_charset_utf8;
 
   catalog_reader_parse ((abstract_catalog_reader_ty *) dcatr, fp, real_filename,
-                        logical_filename, false, input_syntax);
+                        logical_filename, false, input_syntax, arena);
 
   msgdomain_list_ty *mdlp = dcatr->mdlp;
   catalog_reader_free ((abstract_catalog_reader_ty *) dcatr);
index dc4b54503734310aa77b967e7d6133b00d477475..f5a67a61c2b9caa804171a920492d38005ad07dd 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading textual message catalogs (such as PO files).
-   Copyright (C) 1995-2025 Free Software Foundation, Inc.
+   Copyright (C) 1995-2026 Free Software Foundation, Inc.
    This file was written by Bruno Haible <haible@clisp.cons.org>.
 
    This program is free software: you can redistribute it and/or modify
@@ -21,6 +21,7 @@
 #include "message.h"
 #include "read-catalog-abstract.h"
 #include "xerror-handler.h"
+#include "str-list.h"
 
 #include <stdbool.h>
 #include <stdio.h>
@@ -179,7 +180,8 @@ extern msgdomain_list_ty *
                             const char *real_filename,
                             const char *logical_filename,
                             catalog_input_format_ty input_syntax,
-                            xerror_handler_ty xerror_handler);
+                            xerror_handler_ty xerror_handler,
+                            string_list_ty *arena);
 
 
 #ifdef __cplusplus
index ead8f4f77b86496a6de38390d2f02e4da06e776a..62087fcd2013d7a7ed27cd9842d8de89691ac254 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading C# satellite assemblies.
-   Copyright (C) 2003-2025 Free Software Foundation, Inc.
+   Copyright (C) 2003-2026 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -33,6 +33,7 @@
 #include "wait-process.h"
 #include "read-catalog.h"
 #include "read-po.h"
+#include "str-list.h"
 #include "xerror-handler.h"
 #include "xalloc.h"
 #include "concat-filename.h"
@@ -70,8 +71,10 @@ execute_and_read_po_output (const char *progname,
     error (EXIT_FAILURE, errno, _("fdopen() failed"));
 
   /* Read the message list.  */
+  string_list_ty arena;
+  string_list_init (&arena);
   l->mdlp = read_catalog_stream (fp, "(pipe)", "(pipe)", &input_format_po,
-                                 textmode_xerror_handler);
+                                 textmode_xerror_handler, &arena);
 
   fclose (fp);
 
index 02ae3491ff4ab69480fc1e973e57f2352724ec3a..07f7e37f7c3a66658422c114d3e2f91584b2fb68 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading Java ResourceBundles.
-   Copyright (C) 2001-2025 Free Software Foundation, Inc.
+   Copyright (C) 2001-2026 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -33,6 +33,7 @@
 #include "wait-process.h"
 #include "read-catalog.h"
 #include "read-po.h"
+#include "str-list.h"
 #include "xerror-handler.h"
 #include "gettext.h"
 
@@ -67,8 +68,10 @@ execute_and_read_po_output (const char *progname,
     error (EXIT_FAILURE, errno, _("fdopen() failed"));
 
   /* Read the message list.  */
+  string_list_ty arena;
+  string_list_init (&arena);
   l->mdlp = read_catalog_stream (fp, "(pipe)", "(pipe)", &input_format_po,
-                                 textmode_xerror_handler);
+                                 textmode_xerror_handler, &arena);
 
   fclose (fp);
 
index 7723779d50f422026cf239eac99d84e19ee03b95..94127b6acd2d7a15d6c9e72a1c3a7b89f9d7dfb4 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext - internationalization aids
-   Copyright (C) 1995-2025 Free Software Foundation, Inc.
+   Copyright (C) 1995-2026 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>.
    Multibyte character handling by Bruno Haible <haible@clisp.cons.org>.
@@ -784,11 +784,16 @@ mbfile_ungetc (const mbchar_t mbc, mbfile_t mbf)
 /* Prepare lexical analysis.  */
 void
 lex_start (struct po_parser_state *ps,
-           FILE *fp, const char *real_filename, const char *logical_filename)
+           FILE *fp, const char *real_filename, const char *logical_filename,
+           string_list_ty *arena)
 {
   /* Ignore the logical_filename, because PO file entries already have
      their file names attached.  But use real_filename for error messages.  */
-  ps->gram_pos.file_name = xstrdup (real_filename);
+  {
+    char *allocated_file_name = xstrdup (real_filename);
+    string_list_append_move (arena, allocated_file_name);
+    ps->gram_pos.file_name = allocated_file_name;
+  }
 
   mbfile_init (ps->mbf, fp);
 
index 3b700c52378a7fd07dfe92da1390b1ad85786bac..f03a0e46ed4b09c8fefd97e01f2e572fbacefb92 100644 (file)
@@ -24,6 +24,7 @@
 #include <stdbool.h>
 
 #include <error.h>
+#include "str-list.h"
 #include "pos.h"
 #include "read-catalog-abstract.h"
 
@@ -55,7 +56,8 @@ struct po_parser_state;
 /* Prepare lexical analysis.  */
 extern void lex_start (struct po_parser_state *ps,
                        FILE *fp, const char *real_filename,
-                       const char *logical_filename);
+                       const char *logical_filename,
+                       string_list_ty *arena);
 
 /* Terminate lexical analysis.  */
 extern void lex_end (struct po_parser_state *ps);
index e954ef6ea082cbae149af7016e5dc3616b3c95ba..6e7fd58abac56ba37599feb297e4e1d1b1415575 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading PO files.
-   Copyright (C) 1995-2025 Free Software Foundation, Inc.
+   Copyright (C) 1995-2026 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 static void
 po_parse (abstract_catalog_reader_ty *catr, FILE *fp,
           const char *real_filename, const char *logical_filename,
-          bool is_pot_role)
+          bool is_pot_role, string_list_ty *arena)
 {
   struct po_parser_state ps;
   ps.catr = catr;
   ps.gram_pot_role = is_pot_role;
-  lex_start (&ps, fp, real_filename, logical_filename);
+  lex_start (&ps, fp, real_filename, logical_filename, arena);
   po_gram_parse (&ps);
   lex_end (&ps);
 }
index d7e4bf419496b7f269656dc78dc81185a7e3a167..63405f30dac2e0f66499c52d922460187ecddd22 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading Java .properties files.
-   Copyright (C) 2003-2025 Free Software Foundation, Inc.
+   Copyright (C) 2003-2026 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -585,7 +585,7 @@ read_escaped_string (abstract_catalog_reader_ty *catr, bool in_key)
 static void
 properties_parse (abstract_catalog_reader_ty *catr, FILE *file,
                   const char *real_filename, const char *logical_filename,
-                  bool is_pot_role)
+                  bool is_pot_role, string_list_ty *arena)
 {
   /* Read the file into memory.  */
   contents = fread_file (file, 0, &contents_length);
index cff2f7b318f1a939d3088de513460fa7b5f4a027..06b7064b8d257cdd69a13e10bddd11e03710e69f 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading C# .resources files.
-   Copyright (C) 2003-2025 Free Software Foundation, Inc.
+   Copyright (C) 2003-2026 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -33,6 +33,7 @@
 #include "wait-process.h"
 #include "read-catalog.h"
 #include "read-po.h"
+#include "str-list.h"
 #include "xerror-handler.h"
 #include "message.h"
 #include "concat-filename.h"
@@ -71,8 +72,10 @@ execute_and_read_po_output (const char *progname,
     error (EXIT_FAILURE, errno, _("fdopen() failed"));
 
   /* Read the message list.  */
+  string_list_ty arena;
+  string_list_init (&arena);
   l->mdlp = read_catalog_stream (fp, "(pipe)", "(pipe)", &input_format_po,
-                                 textmode_xerror_handler);
+                                 textmode_xerror_handler, &arena);
 
   fclose (fp);
 
index c9a8473982bbab4a1d3a4f69ee04b5878ba896a5..002eadbc343d2a247aaabffaee26bb9b9072d53c 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading NeXTstep/GNUstep .strings files.
-   Copyright (C) 2003-2025 Free Software Foundation, Inc.
+   Copyright (C) 2003-2026 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -809,7 +809,7 @@ read_string (abstract_catalog_reader_ty *catr, lex_pos_ty *start_pos)
 static void
 stringtable_parse (abstract_catalog_reader_ty *catr, FILE *file,
                    const char *real_filename, const char *logical_filename,
-                   bool is_pot_role)
+                   bool is_pot_role, string_list_ty *arena)
 {
   fp = file;
   real_file_name = real_filename;
index 829ef866ffa9d8d8ad31945d627a0ed6a083d841..476ea86f16c46c1ffcdc75d021f1004fcbe4a251 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading tcl/msgcat .msg files.
-   Copyright (C) 2002-2025 Free Software Foundation, Inc.
+   Copyright (C) 2002-2026 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2002.
 
    This program is free software: you can redistribute it and/or modify
@@ -34,6 +34,7 @@
 #include "wait-process.h"
 #include "read-catalog.h"
 #include "read-po.h"
+#include "str-list.h"
 #include "xerror-handler.h"
 #include "xmalloca.h"
 #include "gettext.h"
@@ -99,9 +100,11 @@ msgdomain_read_tcl (const char *locale_name, const char *directory)
     error (EXIT_FAILURE, errno, _("fdopen() failed"));
 
   /* Read the message list.  */
+  string_list_ty arena;
+  string_list_init (&arena);
   msgdomain_list_ty *mdlp =
     read_catalog_stream (fp, "(pipe)", "(pipe)", &input_format_po,
-                         textmode_xerror_handler);
+                         textmode_xerror_handler, &arena);
 
   fclose (fp);
 
index d8aa2a7195b77afbf5489b447138a0952b7eb99b..f2acefeb5d1bf07c82b71a46e2dcab64c7636d47 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext PO, JavaProperties, and NXStringTable backends.
-   Copyright (C) 1995-2025 Free Software Foundation, Inc.
+   Copyright (C) 1995-2026 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
@@ -37,6 +37,7 @@
 #include "read-po.h"
 #include "read-properties.h"
 #include "read-stringtable.h"
+#include "str-list.h"
 #include "msgl-header.h"
 #include "msgl-iconv.h"
 #include "msgl-ascii.h"
@@ -163,8 +164,12 @@ extract (FILE *fp,
   dcatr->file_name = real_filename;
   dcatr->mdlp = NULL;
   dcatr->mlp = mdlp->item[0]->messages;
+
+  string_list_ty arena;
+  string_list_init (&arena);
   catalog_reader_parse ((abstract_catalog_reader_ty *) dcatr, fp, real_filename,
-                        logical_filename, true, input_syntax);
+                        logical_filename, true, input_syntax, &arena);
+
   catalog_reader_free ((abstract_catalog_reader_ty *) dcatr);
 
   if (header_charset != NULL)
index 370230d9543320bc07ea7aac0eb1bd7b85893dc0..52244283d07173e4efcd10ba30f75d387a3b9925 100644 (file)
@@ -1467,7 +1467,12 @@ read_exclusion_file (char *filename)
 
   abstract_catalog_reader_ty *catr =
     catalog_reader_alloc (&exclude_methods, textmode_xerror_handler);
-  catalog_reader_parse (catr, fp, real_filename, filename, true, &input_format_po);
+
+  string_list_ty arena;
+  string_list_init (&arena);
+  catalog_reader_parse (catr, fp, real_filename, filename, true,
+                        &input_format_po, &arena);
+
   catalog_reader_free (catr);
 
   if (fp != stdin)