Re: [PATCHES] Problem with setlocale (found in libecpg) [accessing a

From: Karel Zak <zakkr(at)zf(dot)jcu(dot)cz>
To: Christof Petig <christof(at)petig-baender(dot)de>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>, pgsql-patches(at)postgresql(dot)org, pgsql-hackers(at)postgresql(dot)org
Subject: Re: [PATCHES] Problem with setlocale (found in libecpg) [accessing a
Date: 2001-09-27 08:49:24
Message-ID: 20010927104924.B31778@zf.jcu.cz
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-patches

On Thu, Sep 27, 2001 at 09:26:12AM +0200, Christof Petig wrote:
> Tom Lane wrote:
>
> > >> Well at least on glibc-2.2 it seems that setlocale retuns a pointer to
> > >> malloced memory, and frees this pointer on subsequent calls to
> > >> setlocale.
> > >> So I would kindly ask you to take a second look at every invokation of
> > >> setlocale.
> >
> > I looked around, and am worried about the behavior of PGLC_current()
> > in src/backend/utils/adt/pg_locale.c. It doesn't change locale but
> > does retrieve several successive setlocale() results. Does that work
> > in glibc?
>
> Well actually I did not check glibc's source code. But I tried to run my
> program with efence and it aborted in execute.c

I see locale/setlocale.c in glibc (I'm very like that PG hasn't same
coding style as glibc developers:-). You are right with strdup()/free()
in the setlocale().

>
> [ locale=setlocale(LC_NUMERIC,NULL);
> setlocale(LC_NUMERIC,"C");
> ...
> setlocale(LC_NUMERIC,locale); // access to already freed memory
> (locale)
> ]
>
> So my best guess is that setlocale
> - uses a malloced memory for return (which copes best with variable length
> strings)
> - frees this on a subsequent calls and allocates a new one.
>
> Yes, I'm worried about PGLC_current(), too.

For example to_char() calls PGLC_localeconv(). In the PGLC_localeconv()
is used:

PGLC_current(&lc);
setlocale(LC_ALL, "");
PGLC_setlocale(&lc); /* <-- access to free memory ? */

I see now it in detail and Christof probably found really pretty bug.
Some users already notice something like:

test=# select to_char(45123.4, 'L99G999D9');
NOTICE: pg_setlocale(): 'LC_MONETARY=pŠ-(at)č' cannot be honored.
to_char
-------------
Kč 45 123,4
(1 row)

(I use Czech locales)

We don't see this bug often, because PGLC_localeconv() result is cached
and pg_setlocale is called only once.

It must be fixed for 7.2. May be allocate it in PG, because we need
keep data in PG_LocaleCategories independent on glibc's strdup/free.
May be:

PGLC_current(PG_LocaleCategories * lc)
{
lc->lang = getenv("LANG");

PGLC_free_caltegories(lc);

lc->lc_ctype = pstrdup(setlocale(LC_CTYPE, NULL));

... etc.
}

void
PGLC_free_caltegories(PG_LocaleCategories * lc)
{
if (lc->lc_ctype)
pfree(lc->lc_ctype);

...etc.
}

Comments? I right now work on patch for this.

--
Karel Zak <zakkr(at)zf(dot)jcu(dot)cz>
http://home.zf.jcu.cz/~zakkr/

C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Karel Zak 2001-09-27 08:56:04 Re: multibyte performance
Previous Message Hannu Krosing 2001-09-27 08:00:41 Re: multibyte performance

Browse pgsql-patches by date

  From Date Subject
Next Message Karel Zak 2001-09-27 10:11:15 pg_locale (Was: Re: Problem with setlocale (found in libecpg)...)
Previous Message Christof Petig 2001-09-27 07:26:12 Re: [PATCHES] Problem with setlocale (found in libecpg) [accessing a