Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0d17ce9

Browse files
committed
Fix breakage that had crept into setlocale() usage: once again we've
been bit by the fact that the locale functions return pointers tomodifiable variables. I added some comments that might help us avoidthe mistake in future.
1 parent6c06bc2 commit0d17ce9

File tree

1 file changed

+50
-25
lines changed

1 file changed

+50
-25
lines changed

‎src/backend/utils/adt/pg_locale.c

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
*
33
* PostgreSQL locale utilities
44
*
5-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.19 2002/09/04 20:31:28 momjian Exp $
6-
*
75
* Portions Copyright (c) 2002, PostgreSQL Global Development Group
86
*
7+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.20 2002/10/18 20:44:02 tgl Exp $
8+
*
99
*-----------------------------------------------------------------------
1010
*/
1111

12-
/*
12+
/*----------
1313
* Here is how the locale stuff is handled: LC_COLLATE and LC_CTYPE
1414
* are fixed by initdb, stored in pg_control, and cannot be changed.
1515
* Thus, the effects of strcoll(), strxfrm(), isupper(), toupper(),
@@ -20,14 +20,29 @@
2020
*
2121
* The other categories, LC_MONETARY, LC_NUMERIC, and LC_TIME are also
2222
* settable at run-time. However, we don't actually set those locale
23-
* categories permanently.This would havebizzare effects like no
23+
* categories permanently.This would havebizarre effects like no
2424
* longer accepting standard floating-point literals in some locales.
2525
* Instead, we only set the locales briefly when needed, cache the
2626
* required information obtained from localeconv(), and set them back.
27-
* The information is only used by the formatting functions (to_char,
28-
* etc.) and the money type. For the user, this should all be
27+
* Thecachedinformation is only used by the formatting functions
28+
*(to_char,etc.) and the money type. For the user, this should all be
2929
* transparent. (Actually, LC_TIME doesn't do anything at all right
3030
* now.)
31+
*
32+
* !!! NOW HEAR THIS !!!
33+
*
34+
* We've been bitten repeatedly by this bug, so let's try to keep it in
35+
* mind in future: on some platforms, the locale functions return pointers
36+
* to static data that will be overwritten by any later locale function.
37+
* Thus, for example, the obvious-looking sequence
38+
*save = setlocale(category, NULL);
39+
*if (!setlocale(category, value))
40+
*fail = true;
41+
*setlocale(category, save);
42+
* DOES NOT WORK RELIABLY: on some platforms the second setlocale() call
43+
* will change the memory save is pointing at. To do this sort of thing
44+
* safely, you *must* pstrdup what setlocale returns the first time.
45+
*----------
3146
*/
3247

3348

@@ -64,15 +79,19 @@ locale_xxx_assign(int category, const char *value, bool doit, bool interactive)
6479

6580
save=setlocale(category,NULL);
6681
if (!save)
67-
returnNULL;
82+
returnNULL;/* won't happen, we hope */
83+
84+
/* save may be pointing at a modifiable scratch variable, see above */
85+
save=pstrdup(save);
6886

6987
if (!setlocale(category,value))
70-
returnNULL;
88+
value=NULL;/* set failure return marker */
7189

72-
setlocale(category,save);
90+
setlocale(category,save);/* assume this won't fail */
91+
pfree(save);
7392

74-
/* need to reload cache next time */
75-
if (doit)
93+
/* need to reload cache next time? */
94+
if (doit&&value!=NULL)
7695
CurrentLocaleConvValid= false;
7796

7897
returnvalue;
@@ -99,7 +118,7 @@ locale_time_assign(const char *value, bool doit, bool interactive)
99118

100119

101120
/*
102-
*lc_messages takes effect immediately
121+
*We allow LC_MESSAGES to actually be set globally.
103122
*/
104123
constchar*
105124
locale_messages_assign(constchar*value,booldoit,boolinteractive)
@@ -116,16 +135,7 @@ locale_messages_assign(const char *value, bool doit, bool interactive)
116135
}
117136
else
118137
{
119-
char*save;
120-
121-
save=setlocale(LC_MESSAGES,NULL);
122-
if (!save)
123-
returnNULL;
124-
125-
if (!setlocale(LC_MESSAGES,value))
126-
returnNULL;
127-
128-
setlocale(LC_MESSAGES,save);
138+
value=locale_xxx_assign(LC_MESSAGES,value, false,interactive);
129139
}
130140
#endif
131141
returnvalue;
@@ -210,8 +220,13 @@ PGLC_localeconv(void)
210220

211221
free_struct_lconv(&CurrentLocaleConv);
212222

223+
/* Set user's values of monetary and numeric locales */
213224
save_lc_monetary=setlocale(LC_MONETARY,NULL);
225+
if (save_lc_monetary)
226+
save_lc_monetary=pstrdup(save_lc_monetary);
214227
save_lc_numeric=setlocale(LC_NUMERIC,NULL);
228+
if (save_lc_numeric)
229+
save_lc_numeric=pstrdup(save_lc_numeric);
215230

216231
setlocale(LC_MONETARY,locale_monetary);
217232
setlocale(LC_NUMERIC,locale_numeric);
@@ -221,7 +236,7 @@ PGLC_localeconv(void)
221236

222237
/*
223238
* Must copy all values since restoring internal settings may
224-
* overwrite
239+
* overwrite localeconv()'s results.
225240
*/
226241
CurrentLocaleConv=*extlconv;
227242
CurrentLocaleConv.currency_symbol=strdup(extlconv->currency_symbol);
@@ -236,8 +251,18 @@ PGLC_localeconv(void)
236251
CurrentLocaleConv.positive_sign=strdup(extlconv->positive_sign);
237252
CurrentLocaleConv.n_sign_posn=extlconv->n_sign_posn;
238253

239-
setlocale(LC_MONETARY,save_lc_monetary);
240-
setlocale(LC_NUMERIC,save_lc_numeric);
254+
/* Try to restore internal settings */
255+
if (save_lc_monetary)
256+
{
257+
setlocale(LC_MONETARY,save_lc_monetary);
258+
pfree(save_lc_monetary);
259+
}
260+
261+
if (save_lc_numeric)
262+
{
263+
setlocale(LC_NUMERIC,save_lc_numeric);
264+
pfree(save_lc_numeric);
265+
}
241266

242267
CurrentLocaleConvValid= true;
243268
return&CurrentLocaleConv;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp