zsh-workers
 help / color / mirror / code / Atom feed
From: "Matthias B." <msbREMOVE-THIS@winterdrache.de>
To: zsh-workers@sunsite.dk
Subject: PATCH: incorrect tied param splitting/joining when imeta(separator) is true
Date: Thu, 16 Sep 2004 22:15:35 +0200	[thread overview]
Message-ID: <20040916221535.707ff5fb@buddha.localdomain.de> (raw)
In-Reply-To: <20040913202517.79418def@buddha.localdomain.de>

[-- Attachment #1: Type: text/plain, Size: 971 bytes --]

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

[-- Attachment #2: zsh-4.2.1-split-join-with-meta-sep-fix.patch --]
[-- Type: text/plain, Size: 4287 bytes --]

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

  reply	other threads:[~2004-09-16 20:18 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-09-13 18:25 BUG: tied parameters with NUL-separator Matthias B.
2004-09-16 20:15 ` Matthias B. [this message]
2004-09-17  9:28   ` PATCH: incorrect tied param splitting/joining when imeta(separator) is true Peter Stephenson

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=20040916221535.707ff5fb@buddha.localdomain.de \
    --to=msbremove-this@winterdrache.de \
    --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).