This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ANNOUNCEMENT] TEST RELEASE: Cygwin 2.6.0-0.12


Hi Denis,

On Aug 24 18:07, Denis Excoffier wrote:
> > On 2016-08-23 18:56, Corinna Vinschen <corinna-cygwin@cygwin.com> wrote:
> > 
> > I uploaded a new Cygwin test release 2.6.0-0.12.
> > 
> ...
> > The 2.6.0 release is going to introducing the locale_t datatype, as well
> > as all functions related to locale_t locales and per-thread locales per
> > POSIX-1.2008.
> > 
> > So, rather than just providing a single, per-process locale, you can now
> > create new locales ("newlocale") and set it as locale for the current
> > thread ("uselocale") or use it directly with one of the new functions
> > taking a locale_t as parameter (i.e. isalpha_l).
> > 
> > Since this is brand-new code, this code *will* have bugs.
> > 
> > It would be very helpful if interested developers and Cygwin package
> > maintainers could give this new stuff some good testing.
> > 
> 
> Hello,
> 
> I have exercised the new locale-related code and think i found a problem
> in the strtod_l function (see small test case in gugu.c below).
> [...]
> % cat gugu.c
> //#define _GNU_SOURCE 1
> #include <stdio.h>
> #include <locale.h>
> #include <stdlib.h>
> 
> //
> int main() {
> //
>   locale_t locale = newlocale (LC_ALL_MASK, "C", (locale_t) 0);
>   if (!locale) return 1;
>   char const *nptr = "1.5";
>   char **endptr;
>   double r1 = strtod (nptr, endptr);
>   fprintf (stderr, "r1=%f\n", r1);
>   double r2 = strtod_l (nptr, endptr, locale);
>   fprintf (stderr, "r2=%f\n", r2);
>   return 0;
> };

Uhm... your testcase has two problems:

- _GNU_SOURCE *must* be defined to get the declaration of strtod_l.  You
  can't just omit it.  The warning is serious.  By missing out on the
  declaration the compiler assumes all arguments are of type int.

- The usage of endptr is wrong.  Here's how you do it:

    char *endptr;
    strtod (nptr, &endptr);

  strtod and friends expect endptr to be a pointer to a char *
  which it changes to point to the end of the converted string.
  By giving an uninitialized char ** to strtod, it will write
  the result into a random location.

However, fixing that doesn't avoid the crash in Cygwin, of course.  I
see where the problem is.  The structure used for the "C" locale is
const.  On the other hand, the struct also contains the lconv struct
which gets overwritten by __localeconv_l.  So for the "C" locale this
tries to write into a R/O memory region.

However, since the "C" locale is fixed *and* its lconv is already
initialized, there's no reason at all for __localeconv_l to overwrite
it.

I'll apply a fix to __localeconv_l to just return its lconv without
attempting to write its values when using the "C" locale structure
and upload a -0.13 test release shortly.

Thanks for the report and especially for providing a testcase!


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

Attachment: signature.asc
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]