Fix a small memory leak in libgettextpo.

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.
This commit is contained in:
Bruno Haible 2026-01-25 19:17:48 +01:00
parent 9dda53fc74
commit 910a2e6e06
18 changed files with 86 additions and 38 deletions

View 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);
}

View 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);

View 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);

View 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. */

View 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);

View 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);

View 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

View 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);

View 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);

View 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);

View 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);

View 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
@ -30,12 +30,12 @@
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);
}

View 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);

View 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);

View 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;

View 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);

View 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)

View 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)