zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: zsh-workers@sunsite.dk
Subject: Re: [bug] zsh/datetime strftime bug
Date: Sun, 9 Dec 2007 14:53:32 +0000	[thread overview]
Message-ID: <20071209145332.b41c094f.p.w.stephenson@ntlworld.com> (raw)
In-Reply-To: <237967ef0712081914w19aee904n359825461f7777ec@mail.gmail.com>

On Sun, 9 Dec 2007 04:14:00 +0100
"Mikael Magnusson" <mikachu@gmail.com> wrote:
> > Hi zsh workers !
> >
> > I think I found a bug in strftime:
> >
> > baha@Saito% zsh -f
> > Saito%zmodload zsh/datetime
> > Saito% strftime '%T %x' $EPOCHSECONDS
> > 23:04:17

Yep, that's quite nasty since it's actually a basic problem with
the zsh interface layer to strftime that occurs in prompts, too.  It's
better hidden in the case of prompts because a longer multiplier of the
format string length is used to attempt to create the date/time string.

The basic problem is actually the interface to strftime:  it doesn't
tell you what size of buffer it needs nor allocate it's own memory.
(We've been here before...)  ztrftime() tries to help by returning -1 if
it thinks memory was too short for strftime()... but whoever added that
didn't bother changing the existing returns from returning 0 when it
knows definitely memory was too short.  So the caller blithely assumed 0
just meant the string was zero length, which is correct for the
strftime() interface but not for ztrftime.

I checked this fixed the basic problem first, but also increased the
multiplier of the format length in datetime to be the same as that for
prompts.

Various lessons include (i) the C library is antiquated (ii) if you're
trying to work around it, you need to do it properly (iii) we need yet
more tests, which I haven't done.

Note that writing tests
- doesn't require knowledge of the shell's internals
- is a very good way of learning the shell's syntax in some detail
- is a self-contained problem, not requiring any knowledge beyond
  how the test system works (which isn't complicated except for
  interactive tests)
- is highly beneficial to the quality of the finished product.

> I also noticed this just now,
> {4:11:47:~code/zsh}% grep parameter\ interface Src/Modules/*.c
> Src/Modules/datetime.c: * datetime.c - parameter interface to langinfo
> via curses
> Src/Modules/langinfo.c: * langinfo.c - parameter interface to langinfo
> via curses
> 
> I'm guessing it should say 'parameter interface to strftime' or something.

Indeed.

Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.173
diff -u -r1.173 utils.c
--- Src/utils.c	7 Dec 2007 11:34:50 -0000	1.173
+++ Src/utils.c	9 Dec 2007 14:39:24 -0000
@@ -2389,7 +2389,7 @@
 	     * Fix up some longer cases specially when we get to them.
 	     */
 	    if (ztrftimebuf(&bufsize, 2))
-		return 0;
+		return -1;
 	    switch (*fmt++) {
 	    case 'd':
 		*buf++ = '0' + tm->tm_mday / 10;
@@ -2447,12 +2447,12 @@
 #ifndef HAVE_STRFTIME
 	    case 'a':
 		if (ztrftimebuf(&bufsize, strlen(astr[tm->tm_wday]) -
2))
-		    return 0;
+		    return -1;
 		strucpy(&buf, astr[tm->tm_wday]);
 		break;
 	    case 'b':
 		if (ztrftimebuf(&bufsize, strlen(estr[tm->tm_mon]) -
2))
-		    return 0;
+		    return -1;
 		strucpy(&buf, estr[tm->tm_mon]);
 		break;
 	    case 'p':
@@ -2487,7 +2487,7 @@
 	    }
 	} else {
 	    if (ztrftimebuf(&bufsize, 1))
-		return 0;
+		return -1;
 	    *buf++ = *fmt++;
 	}
     *buf = '\0';
Index: Src/Modules/datetime.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/datetime.c,v
retrieving revision 1.17
diff -u -r1.17 datetime.c
--- Src/Modules/datetime.c	6 Jul 2007 21:52:40 -0000	1.17
+++ Src/Modules/datetime.c	9 Dec 2007 14:39:24 -0000
@@ -1,5 +1,5 @@
 /*
- * datetime.c - parameter interface to langinfo via curses
+ * datetime.c - parameter and command interface to date and time
utilities *
  * This file is part of zsh, the Z shell.
  *
@@ -121,7 +121,7 @@
     }
 
     t = localtime(&secs);
-    bufsize = strlen(argv[0]) * 2;
+    bufsize = strlen(argv[0]) * 8;
     buffer = zalloc(bufsize);
 
     for (x=0; x < 4; x++) {

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


      reply	other threads:[~2007-12-09 14:54 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-09  0:49 antho.charles
2007-12-09  3:14 ` Mikael Magnusson
2007-12-09 14:53   ` Peter Stephenson [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071209145332.b41c094f.p.w.stephenson@ntlworld.com \
    --to=p.w.stephenson@ntlworld.com \
    --cc=zsh-workers@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).