zsh-users
 help / color / mirror / code / Atom feed
* segfault in strftime
@ 2010-02-26 12:08 Sebastian Stark
  2010-02-26 12:52 ` Vincent Lefevre
  2010-02-26 13:03 ` Peter Stephenson
  0 siblings, 2 replies; 10+ messages in thread
From: Sebastian Stark @ 2010-02-26 12:08 UTC (permalink / raw)
  To: zsh-users


I just found that zsh segfaults when I do this:

 zmodload zsh/datetime
 strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673200

while it doesn't for smaller numbers, like:

 strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673199

It will print a negative year for this value though. Negative results are not a big problem I think, but a segfault could be.

I tried this with zsh-4.3.10 under linux-gnu-x86_64. Can anyone reproduce this?


Sebastian

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: segfault in strftime
  2010-02-26 12:08 segfault in strftime Sebastian Stark
@ 2010-02-26 12:52 ` Vincent Lefevre
  2010-02-26 15:07   ` Vincent Lefevre
  2010-02-26 13:03 ` Peter Stephenson
  1 sibling, 1 reply; 10+ messages in thread
From: Vincent Lefevre @ 2010-02-26 12:52 UTC (permalink / raw)
  To: zsh-users

On 2010-02-26 13:08:48 +0100, Sebastian Stark wrote:
> I just found that zsh segfaults when I do this:
> 
>  zmodload zsh/datetime
>  strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673200
> 
> while it doesn't for smaller numbers, like:
> 
>  strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673199
> 
> It will print a negative year for this value though. Negative results are not a big problem I think, but a segfault could be.
> 
> I tried this with zsh-4.3.10 under linux-gnu-x86_64. Can anyone reproduce this?

I can reproduce this under Debian/unstable (zsh 4.3.10).

But under Mac OS X Tiger / PowerPC, with zsh 4.3.10:

strftime: 67768036191673199: result too large

probably because it is only 32 bits. But it seems that a large
positive integer can be regarded as negative:

$ strftime "%a %d.%m.%Y %H:%M:%S" 2776803611
Tue 22.11.1921 15:51:55

Also, it seems to have a problem with -1:

Under Mac OS X:

$ strftime "%a %d.%m.%Y %H:%M:%S" -2
Thu 01.01.1970 00:59:58
$ strftime "%a %d.%m.%Y %H:%M:%S" -1
strftime: -1: unknown error: 0

Under Linux/x86_64 (Debian/unstable):

$ strftime "%a %d.%m.%Y %H:%M:%S" -2
Thu 01.01.1970 00:59:58
$ strftime "%a %d.%m.%Y %H:%M:%S" -1
strftime: -1: success

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: segfault in strftime
  2010-02-26 12:08 segfault in strftime Sebastian Stark
  2010-02-26 12:52 ` Vincent Lefevre
@ 2010-02-26 13:03 ` Peter Stephenson
  2010-02-26 13:59   ` Sebastian Stark
  2010-02-26 14:44   ` Vincent Lefevre
  1 sibling, 2 replies; 10+ messages in thread
From: Peter Stephenson @ 2010-02-26 13:03 UTC (permalink / raw)
  To: zsh-users

Sebastian Stark wrote:
> I just found that zsh segfaults when I do this:
> 
>  zmodload zsh/datetime
>  strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673200
> 
> while it doesn't for smaller numbers, like:
> 
>  strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673199
> 
> It will print a negative year for this value though. Negative results are n=
> ot a big problem I think, but a segfault could be.
> 
> I tried this with zsh-4.3.10 under linux-gnu-x86_64. Can anyone reproduce t=
> his?

I don't see where that would cause a problem, so I'd be interested in a
backtrace---the only place I can see it going wrong is within strtoul().
I'll have a go under that configuration when I get home, but I didn't
get it with a quick go on a 64-bit machine here; I get an ERANGE
everywhere, which means the strtoul() returned an error.  If it didn't,
we got an unsigned long which we converted to time_t, and there's not a
lot left to go wrong.

(I'm not really interested in anyone else's reports unless they can shed
more light on it.)

-- 
Peter Stephenson <pws@csr.com>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: segfault in strftime
  2010-02-26 13:03 ` Peter Stephenson
@ 2010-02-26 13:59   ` Sebastian Stark
  2010-02-26 14:17     ` Peter Stephenson
  2010-02-26 14:44   ` Vincent Lefevre
  1 sibling, 1 reply; 10+ messages in thread
From: Sebastian Stark @ 2010-02-26 13:59 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-users


Am 26.02.2010 um 14:03 schrieb Peter Stephenson:

> Sebastian Stark wrote:
>> I just found that zsh segfaults when I do this:
>> 
>> zmodload zsh/datetime
>> strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673200
>> 
>> while it doesn't for smaller numbers, like:
>> 
>> strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673199
>> 
>> It will print a negative year for this value though. Negative results are n=
>> ot a big problem I think, but a segfault could be.
>> 
>> I tried this with zsh-4.3.10 under linux-gnu-x86_64. Can anyone reproduce t=
>> his?
> 
> I don't see where that would cause a problem, so I'd be interested in a
> backtrace---the only place I can see it going wrong is within strtoul().

The segfault doesn't happen with a time one second before:
sambesi% strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673199
Wed 31.12.-2147481749 23:59:59

This is a freshly compiled zsh 4.3.10 with --enable-zsh-debug.

I'm not used to produce or read backtraces, is the following helpful? Does it mean the problem is my libc?

% gdb --args /usr/local/bin/zsh -f
GNU gdb 6.8-debian             
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu"...
(gdb) run
Starting program: /usr/local/bin/zsh -f
sambesi% echo $ZSH_VERSION
4.3.10
sambesi% zmodload zsh/datetime
sambesi% strftime "%a %d.%m.%Y %H:%M:%S" 67768036191673200

Program received signal SIGSEGV, Segmentation fault.
0x00002ba7cdf4b93b in ?? () from /lib/libc.so.6
(gdb) bt
#0  0x00002ba7cdf4b93b in ?? () from /lib/libc.so.6
#1  0x000000000049bb54 in ztrftime (buf=0x6feed0 "\001J!Χ+", bufsize=158, fmt=0x2ba7cd751832 " %d.%m.%Y %H:%M:%S", tm=0x0)
    at utils.c:2603
#2  0x00002ba7ce8ab18e in bin_strftime (nam=0x2ba7cd751820 "strftime", argv=0x7fffdd4dc980, ops=0x7fffdd4dca60, func=0)
    at datetime.c:128
#3  0x0000000000410731 in execbuiltin (args=0x2ba7cd7517c0, bn=0x2ba7ceaab8a0) at builtin.c:439
#4  0x00000000004313be in execcmd (state=0x7fffdd4dd240, input=0, output=0, how=18, last1=2) at exec.c:3067
#5  0x000000000042cd2c in execpline2 (state=0x7fffdd4dd240, pcode=259, how=18, input=0, output=0, last1=0) at exec.c:1561
#6  0x000000000042bef4 in execpline (state=0x7fffdd4dd240, slcode=5122, how=18, last1=0) at exec.c:1347
#7  0x000000000042b630 in execlist (state=0x7fffdd4dd240, dont_change_job=0, exiting=0) at exec.c:1144
#8  0x000000000042b0bb in execode (p=0x2ba7cd7516e8, dont_change_job=0, exiting=0) at exec.c:975
#9  0x0000000000447a39 in loop (toplevel=1, justonce=0) at init.c:183
#10 0x000000000044a94e in zsh_main (argc=2, argv=0x7fffdd4dd408) at init.c:1409
#11 0x000000000040fb53 in main (argc=2, argv=0x7fffdd4dd408) at ./main.c:93


Sebastian

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: segfault in strftime
  2010-02-26 13:59   ` Sebastian Stark
@ 2010-02-26 14:17     ` Peter Stephenson
  0 siblings, 0 replies; 10+ messages in thread
From: Peter Stephenson @ 2010-02-26 14:17 UTC (permalink / raw)
  To: zsh-users

On Fri, 26 Feb 2010 14:59:09 +0100
Sebastian Stark <seb-zsh@biskalar.de> wrote:
> I'm not used to produce or read backtraces, is the following helpful?

That's very interesting, thank you.

> Does it mean the problem is my libc?

No...

> #1  0x000000000049bb54 in ztrftime (buf=0x6feed0 "\001J!Χ+", bufsize=158, fmt=0x2ba7cd751832 " %d.%m.%Y %H:%M:%S", tm=0x0)
                    ^^^^^^
>     at utils.c:2603

This is the interesting bit.  localtime() dectected a value it couldn't
convert to a structure and returned NULL.  It's allowed to do that if it
didn't like the value passed, though I'm not sure why it wouldn't.  It
seems not all time_t's can be converted to times, a fact I was hitherto
unaware of.

Index: Src/Modules/datetime.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/datetime.c,v
retrieving revision 1.18
diff -p -u -r1.18 datetime.c
--- Src/Modules/datetime.c	9 Dec 2007 14:58:36 -0000	1.18
+++ Src/Modules/datetime.c	26 Feb 2010 14:08:55 -0000
@@ -121,6 +121,10 @@ bin_strftime(char *nam, char **argv, Opt
     }
 
     t = localtime(&secs);
+    if (!t) {
+	zwarnnam(nam, "%s: unable to convert to time", argv[1]);
+	return 1;
+    }
     bufsize = strlen(argv[0]) * 8;
     buffer = zalloc(bufsize);
 

-- 
Peter Stephenson <pws@csr.com>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: segfault in strftime
  2010-02-26 13:03 ` Peter Stephenson
  2010-02-26 13:59   ` Sebastian Stark
@ 2010-02-26 14:44   ` Vincent Lefevre
  1 sibling, 0 replies; 10+ messages in thread
From: Vincent Lefevre @ 2010-02-26 14:44 UTC (permalink / raw)
  To: zsh-users

On 2010-02-26 13:03:28 +0000, Peter Stephenson wrote:
> I don't see where that would cause a problem, so I'd be interested in a
> backtrace---the only place I can see it going wrong is within strtoul().

zsh doesn't check for localtime() failure in datetime.c:

    t = localtime(&secs);
    bufsize = strlen(argv[0]) * 8;
    buffer = zalloc(bufsize);

    for (x=0; x < 4; x++) {
        if (ztrftime(buffer, bufsize, argv[0], t) >= 0)
            break;
        buffer = zrealloc(buffer, bufsize *= 2);
    }

t may be null.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: segfault in strftime
  2010-02-26 12:52 ` Vincent Lefevre
@ 2010-02-26 15:07   ` Vincent Lefevre
  2010-02-26 15:17     ` Peter Stephenson
  0 siblings, 1 reply; 10+ messages in thread
From: Vincent Lefevre @ 2010-02-26 15:07 UTC (permalink / raw)
  To: zsh-users

On 2010-02-26 13:52:56 +0100, Vincent Lefevre wrote:
> Also, it seems to have a problem with -1:
> 
> Under Mac OS X:
> 
> $ strftime "%a %d.%m.%Y %H:%M:%S" -2
> Thu 01.01.1970 00:59:58
> $ strftime "%a %d.%m.%Y %H:%M:%S" -1
> strftime: -1: unknown error: 0
> 
> Under Linux/x86_64 (Debian/unstable):
> 
> $ strftime "%a %d.%m.%Y %H:%M:%S" -2
> Thu 01.01.1970 00:59:58
> $ strftime "%a %d.%m.%Y %H:%M:%S" -1
> strftime: -1: success

Concerning this one:

    secs = (time_t)strtoul(argv[1], &endptr, 10);
    if (secs == (time_t)ULONG_MAX) {
        zwarnnam(nam, "%s: %e", argv[1], errno);
        return 1;
    } else if (*endptr != '\0') {
        zwarnnam(nam, "%s: invalid decimal number", argv[1]);
        return 1;
    }

ULONG_MAX is not necessarily an error! You need to check errno.
The C99 standard says:

  The strtol, strtoll, strtoul, and strtoull functions return the
  converted value, if any. If no conversion could be performed, zero
  is returned. If the correct value is outside the range of
  representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
  ULONG_MAX, or ULLONG_MAX is returned (according to the return type
  and sign of the value, if any), and the value of the macro ERANGE
  is stored in errno.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: segfault in strftime
  2010-02-26 15:07   ` Vincent Lefevre
@ 2010-02-26 15:17     ` Peter Stephenson
  2010-02-26 16:21       ` Vincent Lefevre
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Stephenson @ 2010-02-26 15:17 UTC (permalink / raw)
  To: zsh-users

On Fri, 26 Feb 2010 16:07:49 +0100
Vincent Lefevre <vincent@vinc17.org> wrote:
> > $ strftime "%a %d.%m.%Y %H:%M:%S" -1
> > strftime: -1: success
> 
> Concerning this one:
> 
>     secs = (time_t)strtoul(argv[1], &endptr, 10);
>     if (secs == (time_t)ULONG_MAX) {
>         zwarnnam(nam, "%s: %e", argv[1], errno);
>         return 1;
>     } else if (*endptr != '\0') {
>         zwarnnam(nam, "%s: invalid decimal number", argv[1]);
>         return 1;
>     }
> 
> ULONG_MAX is not necessarily an error! You need to check errno.

I hope we don't need to handle the case sizeof(time_t) > sizeof(unsigned
long).  It's certainly not typical.

Index: Src/Modules/datetime.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/datetime.c,v
retrieving revision 1.19
diff -p -u -r1.19 datetime.c
--- Src/Modules/datetime.c	26 Feb 2010 14:25:05 -0000	1.19
+++ Src/Modules/datetime.c	26 Feb 2010 15:15:12 -0000
@@ -111,8 +111,9 @@ bin_strftime(char *nam, char **argv, Opt
     if (OPT_ISSET(ops, 'r'))
 	return reverse_strftime(nam, argv, scalar, OPT_ISSET(ops, 'q'));
 
+    errno = 0;
     secs = (time_t)strtoul(argv[1], &endptr, 10);
-    if (secs == (time_t)ULONG_MAX) {
+    if (secs == (time_t)ULONG_MAX && errno != 0) {
 	zwarnnam(nam, "%s: %e", argv[1], errno);
 	return 1;
     } else if (*endptr != '\0') {



-- 
Peter Stephenson <pws@csr.com>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: segfault in strftime
  2010-02-26 15:17     ` Peter Stephenson
@ 2010-02-26 16:21       ` Vincent Lefevre
  2010-02-26 16:45         ` Peter Stephenson
  0 siblings, 1 reply; 10+ messages in thread
From: Vincent Lefevre @ 2010-02-26 16:21 UTC (permalink / raw)
  To: zsh-users

On 2010-02-26 15:17:12 +0000, Peter Stephenson wrote:
> I hope we don't need to handle the case sizeof(time_t) >
> sizeof(unsigned long). It's certainly not typical.

The problem would be more a signed time_t that cannot represent
ULONG_MAX: (time_t)ULONG_MAX would have an implementation-defined
behavior, e.g. process killed by a signal. And time_t is typically
defined as a long int!

Wouldn't it be better to test only errno != 0 ?

> Index: Src/Modules/datetime.c
> ===================================================================
> RCS file: /cvsroot/zsh/zsh/Src/Modules/datetime.c,v
> retrieving revision 1.19
> diff -p -u -r1.19 datetime.c
> --- Src/Modules/datetime.c	26 Feb 2010 14:25:05 -0000	1.19
> +++ Src/Modules/datetime.c	26 Feb 2010 15:15:12 -0000
> @@ -111,8 +111,9 @@ bin_strftime(char *nam, char **argv, Opt
>      if (OPT_ISSET(ops, 'r'))
>  	return reverse_strftime(nam, argv, scalar, OPT_ISSET(ops, 'q'));
>  
> +    errno = 0;
>      secs = (time_t)strtoul(argv[1], &endptr, 10);
> -    if (secs == (time_t)ULONG_MAX) {
> +    if (secs == (time_t)ULONG_MAX && errno != 0) {
>  	zwarnnam(nam, "%s: %e", argv[1], errno);
>  	return 1;
>      } else if (*endptr != '\0') {

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: segfault in strftime
  2010-02-26 16:21       ` Vincent Lefevre
@ 2010-02-26 16:45         ` Peter Stephenson
  0 siblings, 0 replies; 10+ messages in thread
From: Peter Stephenson @ 2010-02-26 16:45 UTC (permalink / raw)
  To: zsh-users

Vincent Lefevre wrote:
> Wouldn't it be better to test only errno != 0 ?

Well, given we're setting it to 0 beforehand that seems reasonable.

Index: Src/Modules/datetime.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/datetime.c,v
retrieving revision 1.20
diff -p -u -r1.20 datetime.c
--- Src/Modules/datetime.c	26 Feb 2010 15:30:45 -0000	1.20
+++ Src/Modules/datetime.c	26 Feb 2010 16:44:08 -0000
@@ -113,7 +113,7 @@ bin_strftime(char *nam, char **argv, Opt
 
     errno = 0;
     secs = (time_t)strtoul(argv[1], &endptr, 10);
-    if (secs == (time_t)ULONG_MAX && errno != 0) {
+    if (errno != 0) {
 	zwarnnam(nam, "%s: %e", argv[1], errno);
 	return 1;
     } else if (*endptr != '\0') {


-- 
Peter Stephenson <pws@csr.com>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-02-26 16:45 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-26 12:08 segfault in strftime Sebastian Stark
2010-02-26 12:52 ` Vincent Lefevre
2010-02-26 15:07   ` Vincent Lefevre
2010-02-26 15:17     ` Peter Stephenson
2010-02-26 16:21       ` Vincent Lefevre
2010-02-26 16:45         ` Peter Stephenson
2010-02-26 13:03 ` Peter Stephenson
2010-02-26 13:59   ` Sebastian Stark
2010-02-26 14:17     ` Peter Stephenson
2010-02-26 14:44   ` Vincent Lefevre

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).