This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
intl patches (4)
- To: libc-alpha at sources dot redhat dot com
- Subject: intl patches (4)
- From: Bruno Haible <haible at ilog dot fr>
- Date: Mon, 19 Mar 2001 18:49:27 +0100 (CET)
Too much memory is allocated by the library. For example, after
struct binding
{
struct binding *next;
char *dirname;
char *codeset;
#ifdef __GNUC__
char domainname[0];
#else
char domainname[1];
#endif
};
the expression
malloc (sizeof (struct binding) + len)
allocates alignof(struct binding) (four or eight) bytes too much memory on
non-GCC compilers. The right expression is
malloc (offsetof (struct binding, domainname) + len)
The patch fixes this, and simplifies the declarations by moving the 'ZERO'
macro to an include file.
This patch doesn't cause behaviour changes in glibc.
2001-03-17 Bruno Haible <haible@clisp.cons.org>
* intl/gettextP.h (ZERO): New macro.
(struct binding): Always use ZERO.
* intl/bindtextdom.c (offsetof): Provide fallback for platforms that
lack it, like SunOS4.
(set_binding_values): Use offsetof, not sizeof.
* intl/dcigettext.c (offsetof): Provide fallback for platforms that
lack it, like SunOS4.
(ZERO): Remove macro.
(struct transmem_list): Use ZERO.
(DCIGETTEXT): Use offsetof, not sizeof.
diff -r -c3 intl/gettextP.h intl/gettextP.h
*** intl/gettextP.h Sat Mar 17 17:06:11 2001
--- intl/gettextP.h Sat Mar 17 17:19:19 2001
***************
*** 119,124 ****
--- 119,125 ----
};
+ /* The representation of an opened message catalog. */
struct loaded_domain
{
const char *data;
***************
*** 143,160 ****
unsigned long int nplurals;
};
struct binding
{
struct binding *next;
char *dirname;
char *codeset;
! #ifdef __GNUC__
! char domainname[0];
! #else
! char domainname[1];
! #endif
};
extern int _nl_msg_cat_cntr;
struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
--- 144,170 ----
unsigned long int nplurals;
};
+ /* We want to allocate a string at the end of the struct. But ISO C
+ doesn't allow zero sized arrays. */
+ #ifdef __GNUC__
+ # define ZERO 0
+ #else
+ # define ZERO 1
+ #endif
+
+ /* A set of settings bound to a message domain. Used to store settings
+ from bindtextdomain() and bind_textdomain_codeset(). */
struct binding
{
struct binding *next;
char *dirname;
char *codeset;
! char domainname[ZERO];
};
+ /* A counter which is incremented each time some previous translations
+ become invalid.
+ This variable is part of the external ABI of the GNU libintl. */
extern int _nl_msg_cat_cntr;
struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
diff -r -c3 intl/bindtextdom.c intl/bindtextdom.c
*** intl/bindtextdom.c Sat Mar 17 17:06:11 2001
--- intl/bindtextdom.c Sat Mar 17 17:19:19 2001
***************
*** 64,69 ****
--- 64,74 ----
# define _nl_domain_bindings _nl_domain_bindings__
#endif
+ /* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */
+ #ifndef offsetof
+ # define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
+ #endif
+
/* @@ end of prolog @@ */
/* Contains the default location of the message catalogs. */
***************
*** 233,239 ****
/* We have to create a new binding. */
size_t len = strlen (domainname) + 1;
struct binding *new_binding =
! (struct binding *) malloc (sizeof (*new_binding) + len);
if (__builtin_expect (new_binding == NULL, 0))
goto failed;
--- 238,244 ----
/* We have to create a new binding. */
size_t len = strlen (domainname) + 1;
struct binding *new_binding =
! (struct binding *) malloc (offsetof (struct binding, domainname) + len);
if (__builtin_expect (new_binding == NULL, 0))
goto failed;
diff -r -c3 intl/dcigettext.c intl/dcigettext.c
*** intl/dcigettext.c Sat Mar 17 17:06:11 2001
--- intl/dcigettext.c Sat Mar 17 17:20:01 2001
***************
*** 128,133 ****
--- 128,138 ----
# define _nl_domain_bindings _nl_domain_bindings__
#endif
+ /* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */
+ #ifndef offsetof
+ # define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
+ #endif
+
/* @@ end of prolog @@ */
#ifdef _LIBC
***************
*** 196,209 ****
# define HAVE_LOCALE_NULL
#endif
- /* We want to allocate a string at the end of the struct. gcc makes
- this easy. */
- #ifdef __GNUC__
- # define ZERO 0
- #else
- # define ZERO 1
- #endif
-
/* This is the type used for the search tree where known translations
are stored. */
struct known_translation_t
--- 201,206 ----
***************
*** 335,341 ****
typedef struct transmem_list
{
struct transmem_list *next;
! char data[0];
} transmem_block_t;
static struct transmem_list *transmem_list;
#else
--- 332,338 ----
typedef struct transmem_list
{
struct transmem_list *next;
! char data[ZERO];
} transmem_block_t;
static struct transmem_list *transmem_list;
#else
***************
*** 422,429 ****
/* Try to find the translation among those which we found at
some time. */
! search =
! (struct known_translation_t *) alloca (sizeof (*search) + msgid_len);
memcpy (search->msgid, msgid1, msgid_len);
search->domainname = (char *) domainname;
search->category = category;
--- 419,426 ----
/* Try to find the translation among those which we found at
some time. */
! search = (struct known_translation_t *)
! alloca (offsetof (struct known_translation_t, msgid) + msgid_len);
memcpy (search->msgid, msgid1, msgid_len);
search->domainname = (char *) domainname;
search->category = category;
***************
*** 603,610 ****
struct known_translation_t *newp;
newp = (struct known_translation_t *)
! malloc (sizeof (*newp) + msgid_len
! + domainname_len + 1 - ZERO);
if (newp != NULL)
{
newp->domainname =
--- 630,637 ----
struct known_translation_t *newp;
newp = (struct known_translation_t *)
! malloc (offsetof (struct known_translation_t, msgid)
! + msgid_len + domainname_len + 1);
if (newp != NULL)
{
newp->domainname =