aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2003-11-14 17:30:07 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2003-11-14 17:30:07 +0000
commit991c83ab343917b904ed7fd47a39e8517e15dcd1 (patch)
tree06dbb4726cfe75ef04878b1145de32c616f2aa84
parentf15627d17b8bbf8c6c3623844be509b544d8a9f6 (diff)
downloadzsh-991c83ab343917b904ed7fd47a39e8517e15dcd1.tar.gz
zsh-991c83ab343917b904ed7fd47a39e8517e15dcd1.tar.xz
zsh-991c83ab343917b904ed7fd47a39e8517e15dcd1.zip
19105 shout if interactive without terminal.
19167: BRACE_CCL range with NULL at start. 19168: Sizes using ztrftime were inconsistent. Ports from main line.
-rw-r--r--ChangeLog15
-rw-r--r--Src/glob.c11
-rw-r--r--Src/init.c20
-rw-r--r--Src/jobs.c5
-rw-r--r--Src/prompt.c11
-rw-r--r--Src/utils.c68
-rw-r--r--Test/E01options.ztst13
7 files changed, 121 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index cba407843..454d3de6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -56,6 +56,21 @@
permissions on directories in the fpath; also in case of symlinks,
find parent with ${^fpath:h} rather than ${^fpath}/..
+2003-10-06 Peter Stephenson <pws@pwstephenson.fsnet.co.uk>
+
+ * 19168: Src/prompt.c, Src/utils.c, Src/Modules/datetime.c:
+ various problems with size of buffers and pointer usage
+ in ztrftime().
+
+ * 19167: Src/glob.c, Test/E01options.ztst: NULL at start
+ of BRACE_CCL range didn't work.
+
+2003-09-22 Peter Stephenson <pws@csr.com>
+
+ * 19105: Src/init.c, Src/jobs.c: Set shout to stderr if we
+ are interactive but have no terminal. Prevents crash in
+ history and potentially elsewhere.
+
2003-09-21 Oliver Kiddle <opk@zsh.org>
* users/6606: Completion/Base/Utility/_sep_parts: handle any
diff --git a/Src/glob.c b/Src/glob.c
index 082eea380..c0c75624e 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -1748,12 +1748,13 @@ xpandbraces(LinkList list, LinkNode *np)
* set of flags saying whether each character is present; *
* the final list is in lexical order. */
char ccl[256], *p;
- unsigned char c1, c2, lastch;
+ unsigned char c1, c2;
unsigned int len, pl;
+ int lastch = -1;
uremnode(list, node);
memset(ccl, 0, sizeof(ccl) / sizeof(ccl[0]));
- for (p = str + 1, lastch = 0; p < str2;) {
+ for (p = str + 1; p < str2;) {
if (itok(c1 = *p++))
c1 = ztokens[c1 - STOUC(Pound)];
if ((char) c1 == Meta)
@@ -1762,10 +1763,10 @@ xpandbraces(LinkList list, LinkNode *np)
c2 = ztokens[c2 - STOUC(Pound)];
if ((char) c2 == Meta)
c2 = 32 ^ p[1];
- if (c1 == '-' && lastch && p < str2 && (int)lastch <= (int)c2) {
- while ((int)lastch < (int)c2)
+ if (c1 == '-' && lastch >= 0 && p < str2 && lastch <= (int)c2) {
+ while (lastch < (int)c2)
ccl[lastch++] = 1;
- lastch = 0;
+ lastch = -1;
} else
ccl[lastch = c1] = 1;
}
diff --git a/Src/init.c b/Src/init.c
index 291351b9d..32fd41c9a 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -382,7 +382,13 @@ init_io(void)
#endif
if (shout) {
- fclose(shout);
+ /*
+ * Check if shout was set to stderr, if so don't close it.
+ * We do this if we are interactive but don't have a
+ * terminal.
+ */
+ if (shout != stderr)
+ fclose(shout);
shout = 0;
}
if (SHTTY != -1) {
@@ -451,9 +457,9 @@ init_io(void)
/* We will only use zle if shell is interactive, *
* SHTTY != -1, and shout != 0 */
- if (interact && SHTTY != -1) {
+ if (interact) {
init_shout();
- if(!shout)
+ if(!SHTTY || !shout)
opts[USEZLE] = 0;
} else
opts[USEZLE] = 0;
@@ -486,6 +492,14 @@ mod_export void
init_shout(void)
{
static char shoutbuf[BUFSIZ];
+
+ if (SHTTY == -1)
+ {
+ /* Since we're interative, it's nice to have somewhere to write. */
+ shout = stderr;
+ return;
+ }
+
#if defined(JOB_CONTROL) && defined(TIOCSETD) && defined(NTTYDISC)
int ldisc = NTTYDISC;
diff --git a/Src/jobs.c b/Src/jobs.c
index 120e4a8e6..4912ac88c 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -292,8 +292,9 @@ update_job(Job jn)
}
}
- if (shout && !ttyfrozen && !jn->stty_in_env && !zleactive &&
- job == thisjob && !somestopped && !(jn->stat & STAT_NOSTTY))
+ if (shout && shout != stderr && !ttyfrozen && !jn->stty_in_env &&
+ !zleactive && job == thisjob && !somestopped &&
+ !(jn->stat & STAT_NOSTTY))
gettyinfo(&shttyinfo);
if (isset(MONITOR)) {
diff --git a/Src/prompt.c b/Src/prompt.c
index 43dc12bee..7937bf520 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -479,18 +479,23 @@ putpromptchar(int doprint, int endchar)
tmfmt = "%m/%d/%y";
break;
case 'D':
- if (fm[1] == '{') /*}*/ {
+ if (fm[1] == '{' /*}*/) {
for (ss = fm + 2; *ss && *ss != /*{*/ '}'; ss++)
if(*ss == '\\' && ss[1])
ss++;
dd = tmfmt = tmbuf = zalloc(ss - fm);
- for (ss = fm + 2; *ss && *ss != /*{*/ '}'; ss++) {
+ for (ss = fm + 2; *ss && *ss != /*{*/ '}';
+ ss++) {
if(*ss == '\\' && ss[1])
ss++;
*dd++ = *ss;
}
*dd = 0;
fm = ss - !*ss;
+ if (!*tmfmt) {
+ free(tmbuf);
+ continue;
+ }
} else
tmfmt = "%y-%m-%d";
break;
@@ -502,7 +507,7 @@ putpromptchar(int doprint, int endchar)
tm = localtime(&timet);
for(t0=80; ; t0*=2) {
addbufspc(t0);
- if(ztrftime(bp, t0, tmfmt, tm) != t0)
+ if (ztrftime(bp, t0, tmfmt, tm))
break;
}
bp += strlen(bp);
diff --git a/Src/utils.c b/Src/utils.c
index cf202009f..fafdd99d9 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1660,20 +1660,42 @@ spckword(char **s, int hist, int cmd, int ask)
}
}
+/*
+ * Helper for ztrftime. Called with a pointer to the length left
+ * in the buffer, and a new string length to decrement from that.
+ * Returns 0 if the new length fits, 1 otherwise. We assume a terminating
+ * NUL and return 1 if that doesn't fit.
+ */
+
+/**/
+static int
+ztrftimebuf(int *bufsizeptr, int decr)
+{
+ if (*bufsizeptr <= decr)
+ return 1;
+ *bufsizeptr -= decr;
+ return 0;
+}
+
+/*
+ * Like the system function, this returns the number of characters
+ * copied, not including the terminating NUL. This may be zero
+ * if the string didn't fit.
+ */
+
/**/
mod_export int
ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
{
- int hr12;
+ int hr12, decr;
#ifndef HAVE_STRFTIME
static char *astr[] =
{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
static char *estr[] =
{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec"};
-#else
- char *origbuf = buf;
#endif
+ char *origbuf = buf;
char tmp[3];
@@ -1682,6 +1704,14 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
while (*fmt)
if (*fmt == '%') {
fmt++;
+ /*
+ * Assume this format will take up at least two
+ * characters. Not always true, but if that matters
+ * we are so close to the edge it's not a big deal.
+ * Fix up some longer cases specially when we get to them.
+ */
+ if (ztrftimebuf(&bufsize, 2))
+ return 0;
switch (*fmt++) {
case 'd':
*buf++ = '0' + tm->tm_mday / 10;
@@ -1709,9 +1739,10 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
if (hr12 == 0)
hr12 = 12;
if (hr12 > 9)
- *buf++ = '1';
+ *buf++ = '1';
else if (fmt[-1] == 'l')
- *buf++ = ' ';
+ *buf++ = ' ';
+
*buf++ = '0' + (hr12 % 10);
break;
case 'm':
@@ -1730,11 +1761,20 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
*buf++ = '0' + (tm->tm_year / 10) % 10;
*buf++ = '0' + tm->tm_year % 10;
break;
+ case '\0':
+ /* Guard against premature end of string */
+ *buf++ = '%';
+ fmt--;
+ break;
#ifndef HAVE_STRFTIME
case 'a':
+ if (ztrftimebuf(&bufsize, strlen(astr[tm->tm_wday]) - 2))
+ return 0;
strucpy(&buf, astr[tm->tm_wday]);
break;
case 'b':
+ if (ztrftimebuf(&bufsize, strlen(estr[tm->tm_mon]) - 2))
+ return 0;
strucpy(&buf, estr[tm->tm_mon]);
break;
case 'p':
@@ -1747,17 +1787,27 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
*buf++ = fmt[-1];
#else
default:
+ /*
+ * Remember we've already allowed for two characters
+ * in the accounting in bufsize (but nowhere else).
+ */
*buf = '\0';
tmp[1] = fmt[-1];
- strftime(buf, bufsize - strlen(origbuf), tmp, tm);
- buf += strlen(buf);
+ if (!strftime(buf, bufsize + 2, tmp, tm))
+ return 0;
+ decr = strlen(buf);
+ buf += decr;
+ bufsize -= decr - 2;
#endif
break;
}
- } else
+ } else {
+ if (ztrftimebuf(&bufsize, 1))
+ return 0;
*buf++ = *fmt++;
+ }
*buf = '\0';
- return 0;
+ return buf - origbuf;
}
/**/
diff --git a/Test/E01options.ztst b/Test/E01options.ztst
index 99f9f6fae..7b520078e 100644
--- a/Test/E01options.ztst
+++ b/Test/E01options.ztst
@@ -154,6 +154,19 @@
>a b c d
>{abcd}
+# Don't use NUL as a field separator in the following.
+ setopt braceccl
+ print {$'\0'-$'\5'} | IFS=' ' read -A chars
+ for c in $chars; do print $(( #c )); done
+ unsetopt braceccl
+0:BRACE_CCL option starting from NUL
+>0
+>1
+>2
+>3
+>4
+>5
+
setopt bsdecho
echo "histon\nimpington"
echo -e "girton\ncottenham"