Fix memory handling in functions called from loadlocale
Signed-off by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
aefd8b5b51
commit
1afa0fe4b3
|
@ -74,13 +74,21 @@ __ctype_load_locale (struct __locale_t *locale, const char *name,
|
||||||
{
|
{
|
||||||
ctp = (struct lc_ctype_T *) calloc (1, sizeof *ctp);
|
ctp = (struct lc_ctype_T *) calloc (1, sizeof *ctp);
|
||||||
if (!ctp)
|
if (!ctp)
|
||||||
return -1;
|
{
|
||||||
memcpy (ctp, &ct, sizeof *ctp);
|
free (bufp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*ctp = ct;
|
||||||
}
|
}
|
||||||
|
struct __lc_cats tmp = locale->lc_cat[LC_CTYPE];
|
||||||
locale->lc_cat[LC_CTYPE].ptr = ret == 0 ? &_C_ctype_locale : ctp;
|
locale->lc_cat[LC_CTYPE].ptr = ret == 0 ? &_C_ctype_locale : ctp;
|
||||||
if (locale->lc_cat[LC_CTYPE].buf)
|
|
||||||
free (locale->lc_cat[LC_CTYPE].buf);
|
|
||||||
locale->lc_cat[LC_CTYPE].buf = bufp;
|
locale->lc_cat[LC_CTYPE].buf = bufp;
|
||||||
|
/* If buf is not NULL, both pointers have been alloc'ed */
|
||||||
|
if (tmp.buf)
|
||||||
|
{
|
||||||
|
free ((void *) tmp.ptr);
|
||||||
|
free (tmp.buf);
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
#elif !defined (__HAVE_LOCALE_INFO_EXTENDED__)
|
#elif !defined (__HAVE_LOCALE_INFO_EXTENDED__)
|
||||||
|
|
|
@ -84,13 +84,21 @@ __messages_load_locale (struct __locale_t *locale, const char *name,
|
||||||
{
|
{
|
||||||
mep = (struct lc_messages_T *) calloc (1, sizeof *mep);
|
mep = (struct lc_messages_T *) calloc (1, sizeof *mep);
|
||||||
if (!mep)
|
if (!mep)
|
||||||
return -1;
|
{
|
||||||
memcpy (mep, &me, sizeof *mep);
|
free (bufp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*mep = me;
|
||||||
}
|
}
|
||||||
|
struct __lc_cats tmp = locale->lc_cat[LC_MESSAGES];
|
||||||
locale->lc_cat[LC_MESSAGES].ptr = ret == 0 ? &_C_messages_locale : mep;
|
locale->lc_cat[LC_MESSAGES].ptr = ret == 0 ? &_C_messages_locale : mep;
|
||||||
if (locale->lc_cat[LC_MESSAGES].buf)
|
|
||||||
free (locale->lc_cat[LC_MESSAGES].buf);
|
|
||||||
locale->lc_cat[LC_MESSAGES].buf = bufp;
|
locale->lc_cat[LC_MESSAGES].buf = bufp;
|
||||||
|
/* If buf is not NULL, both pointers have been alloc'ed */
|
||||||
|
if (tmp.buf)
|
||||||
|
{
|
||||||
|
free ((void *) tmp.ptr);
|
||||||
|
free (tmp.buf);
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -112,13 +112,21 @@ __monetary_load_locale (struct __locale_t *locale, const char *name ,
|
||||||
{
|
{
|
||||||
mop = (struct lc_monetary_T *) calloc (1, sizeof *mop);
|
mop = (struct lc_monetary_T *) calloc (1, sizeof *mop);
|
||||||
if (!mop)
|
if (!mop)
|
||||||
return -1;
|
{
|
||||||
memcpy (mop, &mo, sizeof *mop);
|
free (bufp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*mop = mo;
|
||||||
}
|
}
|
||||||
|
struct __lc_cats tmp = locale->lc_cat[LC_MONETARY];
|
||||||
locale->lc_cat[LC_MONETARY].ptr = ret == 0 ? &_C_monetary_locale : mop;
|
locale->lc_cat[LC_MONETARY].ptr = ret == 0 ? &_C_monetary_locale : mop;
|
||||||
if (locale->lc_cat[LC_MONETARY].buf)
|
|
||||||
free (locale->lc_cat[LC_MONETARY].buf);
|
|
||||||
locale->lc_cat[LC_MONETARY].buf = bufp;
|
locale->lc_cat[LC_MONETARY].buf = bufp;
|
||||||
|
/* If buf is not NULL, both pointers have been alloc'ed */
|
||||||
|
if (tmp.buf)
|
||||||
|
{
|
||||||
|
free ((void *) tmp.ptr);
|
||||||
|
free (tmp.buf);
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -74,13 +74,21 @@ __numeric_load_locale (struct __locale_t *locale, const char *name ,
|
||||||
{
|
{
|
||||||
nmp = (struct lc_numeric_T *) calloc (1, sizeof *nmp);
|
nmp = (struct lc_numeric_T *) calloc (1, sizeof *nmp);
|
||||||
if (!nmp)
|
if (!nmp)
|
||||||
return -1;
|
{
|
||||||
memcpy (nmp, &nm, sizeof *nmp);
|
free (bufp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*nmp = nm;
|
||||||
}
|
}
|
||||||
|
struct __lc_cats tmp = locale->lc_cat[LC_NUMERIC];
|
||||||
locale->lc_cat[LC_NUMERIC].ptr = ret == 0 ? &_C_numeric_locale : nmp;
|
locale->lc_cat[LC_NUMERIC].ptr = ret == 0 ? &_C_numeric_locale : nmp;
|
||||||
if (locale->lc_cat[LC_NUMERIC].buf)
|
|
||||||
free (locale->lc_cat[LC_NUMERIC].buf);
|
|
||||||
locale->lc_cat[LC_NUMERIC].buf = bufp;
|
locale->lc_cat[LC_NUMERIC].buf = bufp;
|
||||||
|
/* If buf is not NULL, both pointers have been alloc'ed */
|
||||||
|
if (tmp.buf)
|
||||||
|
{
|
||||||
|
free ((void *) tmp.ptr);
|
||||||
|
free (tmp.buf);
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1152,7 +1152,10 @@ error:
|
||||||
for (i = 1; i < _LC_LAST; ++i)
|
for (i = 1; i < _LC_LAST; ++i)
|
||||||
if (tmp_locale.lc_cat[i].buf
|
if (tmp_locale.lc_cat[i].buf
|
||||||
&& tmp_locale.lc_cat[i].buf != (const void *) -1)
|
&& tmp_locale.lc_cat[i].buf != (const void *) -1)
|
||||||
_free_r (p, tmp_locale.lc_cat[i].buf);
|
{
|
||||||
|
_free_r (p, tmp_locale.lc_cat[i].ptr);
|
||||||
|
_free_r (p, tmp_locale.lc_cat[i].buf);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1167,7 +1170,10 @@ _freelocale_r (struct _reent *p, struct __locale_t *locobj)
|
||||||
#ifdef __HAVE_LOCALE_INFO__
|
#ifdef __HAVE_LOCALE_INFO__
|
||||||
for (int i = 1; i < _LC_LAST; ++i)
|
for (int i = 1; i < _LC_LAST; ++i)
|
||||||
if (locobj->lc_cat[i].buf)
|
if (locobj->lc_cat[i].buf)
|
||||||
_free_r (p, locobj->lc_cat[i].buf);
|
{
|
||||||
|
_free_r (p, locobj->lc_cat[i].ptr);
|
||||||
|
_free_r (p, locobj->lc_cat[i].buf);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
_free_r (p, locobj);
|
_free_r (p, locobj);
|
||||||
}
|
}
|
||||||
|
@ -1212,7 +1218,10 @@ error:
|
||||||
#ifdef __HAVE_LOCALE_INFO__
|
#ifdef __HAVE_LOCALE_INFO__
|
||||||
while (--i > 0)
|
while (--i > 0)
|
||||||
if (tmp_locale.lc_cat[i].buf)
|
if (tmp_locale.lc_cat[i].buf)
|
||||||
_free_r (p, tmp_locale.lc_cat[i].buf);
|
{
|
||||||
|
_free_r (p, tmp_locale.lc_cat[i].ptr);
|
||||||
|
_free_r (p, tmp_locale.lc_cat[i].buf);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -174,13 +174,21 @@ __time_load_locale (struct __locale_t *locale, const char *name,
|
||||||
{
|
{
|
||||||
tip = (struct lc_time_T *) calloc (1, sizeof *tip);
|
tip = (struct lc_time_T *) calloc (1, sizeof *tip);
|
||||||
if (!tip)
|
if (!tip)
|
||||||
return -1;
|
{
|
||||||
memcpy (tip, &ti, sizeof *tip);
|
free (bufp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*tip = ti;
|
||||||
}
|
}
|
||||||
|
struct __lc_cats tmp = locale->lc_cat[LC_TIME];
|
||||||
locale->lc_cat[LC_TIME].ptr = ret == 0 ? &_C_time_locale : tip;
|
locale->lc_cat[LC_TIME].ptr = ret == 0 ? &_C_time_locale : tip;
|
||||||
if (locale->lc_cat[LC_TIME].buf)
|
|
||||||
free (locale->lc_cat[LC_TIME].buf);
|
|
||||||
locale->lc_cat[LC_TIME].buf = bufp;
|
locale->lc_cat[LC_TIME].buf = bufp;
|
||||||
|
/* If buf is not NULL, both pointers have been alloc'ed */
|
||||||
|
if (tmp.buf)
|
||||||
|
{
|
||||||
|
free ((void *) tmp.ptr);
|
||||||
|
free (tmp.buf);
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1066,6 +1066,13 @@ __set_lc_messages_from_win (const char *name,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct lc_collate_T _C_collate_locale =
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
__ascii_mbtowc,
|
||||||
|
"ASCII"
|
||||||
|
};
|
||||||
|
|
||||||
/* Called from newlib's setlocale() if category is LC_COLLATE. Stores
|
/* Called from newlib's setlocale() if category is LC_COLLATE. Stores
|
||||||
LC_COLLATE locale information. This is subsequently accessed by the
|
LC_COLLATE locale information. This is subsequently accessed by the
|
||||||
below functions strcoll, strxfrm, wcscoll, wcsxfrm. */
|
below functions strcoll, strxfrm, wcscoll, wcsxfrm. */
|
||||||
|
@ -1073,42 +1080,39 @@ extern "C" int
|
||||||
__collate_load_locale (struct __locale_t *locale, const char *name,
|
__collate_load_locale (struct __locale_t *locale, const char *name,
|
||||||
void *f_mbtowc, const char *charset)
|
void *f_mbtowc, const char *charset)
|
||||||
{
|
{
|
||||||
const struct lc_collate_T *ccop;
|
|
||||||
char *bufp = NULL;
|
char *bufp = NULL;
|
||||||
|
struct lc_collate_T *cop = NULL;
|
||||||
|
|
||||||
LCID lcid = __get_lcid_from_locale (name);
|
LCID lcid = __get_lcid_from_locale (name);
|
||||||
if (lcid == (LCID) -1)
|
if (lcid == (LCID) -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (!lcid)
|
if (lcid)
|
||||||
{
|
{
|
||||||
ccop = &_C_collate_locale;
|
bufp = (char *) malloc (1); /* dummy */
|
||||||
bufp = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bufp = (char *) calloc (1, sizeof (struct lc_collate_T));
|
|
||||||
if (!bufp)
|
if (!bufp)
|
||||||
return -1;
|
return -1;
|
||||||
struct lc_collate_T *cop = (struct lc_collate_T *) bufp;
|
cop = (struct lc_collate_T *) calloc (1, sizeof (struct lc_collate_T));
|
||||||
|
if (!cop)
|
||||||
|
{
|
||||||
|
free (bufp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
cop->lcid = lcid;
|
cop->lcid = lcid;
|
||||||
cop->mbtowc = (mbtowc_p) f_mbtowc;
|
cop->mbtowc = (mbtowc_p) f_mbtowc;
|
||||||
stpcpy (cop->codeset, charset);
|
stpcpy (cop->codeset, charset);
|
||||||
ccop = (const struct lc_collate_T *) cop;
|
|
||||||
}
|
}
|
||||||
locale->lc_cat[LC_COLLATE].ptr = ccop;
|
struct __lc_cats tmp = locale->lc_cat[LC_COLLATE];
|
||||||
if (locale->lc_cat[LC_COLLATE].buf)
|
locale->lc_cat[LC_COLLATE].ptr = lcid == 0 ? &_C_collate_locale : cop;
|
||||||
free (locale->lc_cat[LC_COLLATE].buf);
|
|
||||||
locale->lc_cat[LC_COLLATE].buf = bufp;
|
locale->lc_cat[LC_COLLATE].buf = bufp;
|
||||||
|
/* If buf is not NULL, both pointers have been alloc'ed */
|
||||||
|
if (tmp.buf)
|
||||||
|
{
|
||||||
|
free ((void *) tmp.ptr);
|
||||||
|
free (tmp.buf);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct lc_collate_T _C_collate_locale =
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
__ascii_mbtowc,
|
|
||||||
"ASCII"
|
|
||||||
};
|
|
||||||
|
|
||||||
/* We use the Windows functions for locale-specific string comparison and
|
/* We use the Windows functions for locale-specific string comparison and
|
||||||
transformation. The advantage is that we don't need any files with
|
transformation. The advantage is that we don't need any files with
|
||||||
collation information. */
|
collation information. */
|
||||||
|
|
Loading…
Reference in New Issue