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); | ||||
| 	  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; | ||||
|       if (locale->lc_cat[LC_CTYPE].buf) | ||||
| 	free (locale->lc_cat[LC_CTYPE].buf); | ||||
|       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; | ||||
|     } | ||||
| #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); | ||||
| 	  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; | ||||
|       if (locale->lc_cat[LC_MESSAGES].buf) | ||||
| 	free (locale->lc_cat[LC_MESSAGES].buf); | ||||
|       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; | ||||
|     } | ||||
| #else | ||||
|  |  | |||
|  | @ -112,13 +112,21 @@ __monetary_load_locale (struct __locale_t *locale, const char *name , | |||
| 	{ | ||||
| 	  mop = (struct lc_monetary_T *) calloc (1, sizeof *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; | ||||
|       if (locale->lc_cat[LC_MONETARY].buf) | ||||
| 	free (locale->lc_cat[LC_MONETARY].buf); | ||||
|       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; | ||||
|     } | ||||
| #else | ||||
|  |  | |||
|  | @ -74,13 +74,21 @@ __numeric_load_locale (struct __locale_t *locale, const char *name , | |||
| 	{ | ||||
| 	  nmp = (struct lc_numeric_T *) calloc (1, sizeof *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; | ||||
|       if (locale->lc_cat[LC_NUMERIC].buf) | ||||
| 	free (locale->lc_cat[LC_NUMERIC].buf); | ||||
|       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; | ||||
|     } | ||||
| #else | ||||
|  |  | |||
|  | @ -1152,7 +1152,10 @@ error: | |||
|   for (i = 1; i < _LC_LAST; ++i) | ||||
|     if (tmp_locale.lc_cat[i].buf | ||||
| 	&& 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 | ||||
| 
 | ||||
|   return NULL; | ||||
|  | @ -1167,7 +1170,10 @@ _freelocale_r (struct _reent *p, struct __locale_t *locobj) | |||
| #ifdef __HAVE_LOCALE_INFO__ | ||||
|   for (int i = 1; i < _LC_LAST; ++i) | ||||
|     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 | ||||
|   _free_r (p, locobj); | ||||
| } | ||||
|  | @ -1212,7 +1218,10 @@ error: | |||
| #ifdef __HAVE_LOCALE_INFO__ | ||||
|   while (--i > 0) | ||||
|     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 | ||||
| 
 | ||||
|   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); | ||||
| 	  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; | ||||
|       if (locale->lc_cat[LC_TIME].buf) | ||||
| 	free (locale->lc_cat[LC_TIME].buf); | ||||
|       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; | ||||
|     } | ||||
| #else | ||||
|  |  | |||
|  | @ -1066,6 +1066,13 @@ __set_lc_messages_from_win (const char *name, | |||
|   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
 | ||||
|    LC_COLLATE locale information.  This is subsequently accessed by the | ||||
|    below functions strcoll, strxfrm, wcscoll, wcsxfrm. */ | ||||
|  | @ -1073,42 +1080,39 @@ extern "C" int | |||
| __collate_load_locale (struct __locale_t *locale, const char *name, | ||||
| 		       void *f_mbtowc, const char *charset) | ||||
| { | ||||
|   const struct lc_collate_T *ccop; | ||||
|   char *bufp = NULL; | ||||
|   struct lc_collate_T *cop = NULL; | ||||
| 
 | ||||
|   LCID lcid = __get_lcid_from_locale (name); | ||||
|   if (lcid == (LCID) -1) | ||||
|     return -1; | ||||
|   if (!lcid) | ||||
|   if (lcid) | ||||
|     { | ||||
|       ccop = &_C_collate_locale; | ||||
|       bufp = NULL; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       bufp = (char *) calloc (1, sizeof (struct lc_collate_T)); | ||||
|       bufp = (char *) malloc (1);	/* dummy */ | ||||
|       if (!bufp) | ||||
| 	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->mbtowc = (mbtowc_p) f_mbtowc; | ||||
|       stpcpy (cop->codeset, charset); | ||||
|       ccop = (const struct lc_collate_T *) cop; | ||||
|     } | ||||
|   locale->lc_cat[LC_COLLATE].ptr = ccop; | ||||
|   if (locale->lc_cat[LC_COLLATE].buf) | ||||
|     free (locale->lc_cat[LC_COLLATE].buf); | ||||
|   struct __lc_cats tmp = locale->lc_cat[LC_COLLATE]; | ||||
|   locale->lc_cat[LC_COLLATE].ptr = lcid == 0 ? &_C_collate_locale : cop; | ||||
|   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; | ||||
| } | ||||
| 
 | ||||
| const struct lc_collate_T _C_collate_locale = | ||||
| { | ||||
|   0, | ||||
|   __ascii_mbtowc, | ||||
|   "ASCII" | ||||
| }; | ||||
| 
 | ||||
| /* We use the Windows functions for locale-specific string comparison and
 | ||||
|    transformation.  The advantage is that we don't need any files with | ||||
|    collation information. */ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue