Re: [PATCHES] Problem with setlocale (found in libecpg) [accessing a - Mailing list pgsql-hackers

From Karel Zak
Subject Re: [PATCHES] Problem with setlocale (found in libecpg) [accessing a
Date
Msg-id 20010927104924.B31778@zf.jcu.cz
Whole thread Raw
In response to Re: [PATCHES] Problem with setlocale (found in libecpg) [accessing a  (Christof Petig <christof@petig-baender.de>)
List pgsql-hackers
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Š-@č' 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@zf.jcu.cz>
 http://home.zf.jcu.cz/~zakkr/

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

pgsql-hackers by date:

Previous
From: Karel Zak
Date:
Subject: Re: multibyte performance
Next
From: Haller Christoph
Date:
Subject: Abort transaction on duplicate key error