Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: incorrect tied param splitting/joining when imeta(separator) is true
- X-seq: zsh-workers 20378
- From: "Matthias B." <msbREMOVE-THIS@xxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxx
- Subject: PATCH: incorrect tied param splitting/joining when imeta(separator) is true
- Date: Thu, 16 Sep 2004 22:15:35 +0200
- In-reply-to: <20040913202517.79418def@xxxxxxxxxxxxxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <20040913202517.79418def@xxxxxxxxxxxxxxxxxxxxx>
Since no one seemed to be interested in the NUL-separator bugs I've taken
a look at the code myself and I've managed to locate the bugs.
The function tiedarrsetfn() does not convert characters for which imeta()
is true into separator strings properly. This means that the bug is not
limited to NUL-characters but affects all characters for which imeta() is
true (e.g. 0x83).
There are also 2 bugs in zjoin():
1. zjoin() doesn't put the NUL-terminator in the right place when delim is
a meta-character.
2. zjoin() refuses to add 0-delimiters (although it does count them when
computing the length). This behaviour does not seem to be used anywhere in
zsh code AFAICS and even if it were, that would be a bug in the respective
call.
The attached patch fixes both problems and adds 2 regression tests to
B02typeset.ztst (both tests are necessary, since 0 and 0x83 are treated
differently in some places, so that one case could regress independent of
the other).
MSB
diff -r --unified=23 zsh-4.2.1/Src/params.c zsh-4.2.1-split-join-with-meta-sep-fix/Src/params.c
--- zsh-4.2.1/Src/params.c Fri Aug 13 12:22:45 2004
+++ zsh-4.2.1-split-join-with-meta-sep-fix/Src/params.c Thu Sep 16 19:34:59 2004
@@ -2623,47 +2623,47 @@
}
/**/
char *
tiedarrgetfn(Param pm)
{
struct tieddata *dptr = (struct tieddata *)pm->u.data;
return *dptr->arrptr ? zjoin(*dptr->arrptr, dptr->joinchar, 1) : "";
}
/**/
void
tiedarrsetfn(Param pm, char *x)
{
struct tieddata *dptr = (struct tieddata *)pm->u.data;
if (*dptr->arrptr)
freearray(*dptr->arrptr);
if (x) {
char sepbuf[3];
if (imeta(dptr->joinchar))
{
sepbuf[0] = Meta;
- sepbuf[1] = dptr->joinchar;
+ sepbuf[1] = dptr->joinchar ^ 32;
sepbuf[2] = '\0';
}
else
{
sepbuf[0] = dptr->joinchar;
sepbuf[1] = '\0';
}
*dptr->arrptr = sepsplit(x, sepbuf, 0, 0);
if (pm->flags & PM_UNIQUE)
uniqarray(*dptr->arrptr);
} else
*dptr->arrptr = NULL;
if (pm->ename)
arrfixenv(pm->nam, *dptr->arrptr);
zsfree(x);
}
/**/
void
tiedarrunsetfn(Param pm, UNUSED(int exp))
{
/*
* Special unset function because we allocated a struct tieddata
diff -r --unified=23 zsh-4.2.1/Src/utils.c zsh-4.2.1-split-join-with-meta-sep-fix/Src/utils.c
--- zsh-4.2.1/Src/utils.c Fri Aug 13 12:22:46 2004
+++ zsh-4.2.1-split-join-with-meta-sep-fix/Src/utils.c Thu Sep 16 21:25:56 2004
@@ -1853,56 +1853,54 @@
} else {
if (ztrftimebuf(&bufsize, 1))
return 0;
*buf++ = *fmt++;
}
*buf = '\0';
return buf - origbuf;
}
/**/
mod_export char *
zjoin(char **arr, int delim, int heap)
{
int len = 0;
char **s, *ret, *ptr;
for (s = arr; *s; s++)
len += strlen(*s) + 1 + (imeta(delim) ? 1 : 0);
if (!len)
return heap? "" : ztrdup("");
ptr = ret = (heap ? (char *) hcalloc(len) : (char *) zshcalloc(len));
for (s = arr; *s; s++) {
strucpy(&ptr, *s);
- if (delim) {
if (imeta(delim)) {
*ptr++ = Meta;
*ptr++ = delim ^ 32;
}
else
*ptr++ = delim;
- }
}
- ptr[-1] = '\0';
+ ptr[-1 - (imeta(delim) ? 1 : 0)] = '\0';
return ret;
}
/* Split a string containing a colon separated list *
* of items into an array of strings. */
/**/
char **
colonsplit(char *s, int uniq)
{
int ct;
char *t, **ret, **ptr, **p;
for (t = s, ct = 0; *t; t++) /* count number of colons */
if (*t == ':')
ct++;
ptr = ret = (char **) zalloc(sizeof(char **) * (ct + 2));
t = s;
do {
s = t;
/* move t to point at next colon */
for (; *t && *t != ':'; t++);
diff -r --unified=23 zsh-4.2.1/Test/B02typeset.ztst zsh-4.2.1-split-join-with-meta-sep-fix/Test/B02typeset.ztst
--- zsh-4.2.1/Test/B02typeset.ztst Fri Aug 13 12:22:54 2004
+++ zsh-4.2.1-split-join-with-meta-sep-fix/Test/B02typeset.ztst Thu Sep 16 21:58:41 2004
@@ -163,46 +163,61 @@
?(eval):3: read-only variable: r
typeset r=success
readonly r
print $r
r=failure
1:Convert to readonly
>success
?(eval):4: read-only variable: r
typeset -gU array
print $array
0:Uniquified arrays and non-local scope
>a r y
typeset -T SCALAR=l:o:c:a:l array
print $array
typeset -U SCALAR
print $SCALAR $array
0:Tied parameters and uniquified colon-arrays
>l o c a l
>l:o:c:a l o c a
+ typeset -T SCALAR=$'l\x83o\x83c\x83a\x83l' array $'\x83'
+ print $array
+ typeset -U SCALAR
+ print $SCALAR $array
+0:Tied parameters and uniquified arrays with meta-character as separator
+>l o c a l
+>l?o?c?a l o c a
+
+ typeset -T SCALAR=$'l\000o\000c\000a\000l' array $'\000'
+ typeset -U SCALAR
+ print $array
+ [[ $SCALAR == $'l\000o\000c\000a' ]]
+0:Tied parameters and uniquified arrays with NUL-character as separator
+>l o c a
+
typeset -T SCALAR array
typeset +T SCALAR
1:Untying is prohibited
?(eval):typeset:2: use unset to remove tied variables
OUTER=outer
scope13
print $OUTER
0:Export of tied parameters
>i:n:n:e:r
>outer
typeset -TU MORESTUFF=here-we-go-go-again morestuff '-'
print -l $morestuff
0:Tied arrays with separator specified
>here
>we
>go
>again
typeset -T THIS will not work
1:Tied array syntax
?(eval):typeset:1: -T requires names of scalar and array
Messages sorted by:
Reverse Date,
Date,
Thread,
Author