zsh-workers
 help / color / mirror / code / Atom feed
From: Zefram <zefram@dcs.warwick.ac.uk>
To: zsh-workers@math.gatech.edu (Z Shell workers mailing list)
Subject: two metafication bugs
Date: Wed, 4 Dec 1996 10:28:34 +0000 (GMT)	[thread overview]
Message-ID: <26987.199612041028@stone.dcs.warwick.ac.uk> (raw)

-----BEGIN PGP SIGNED MESSAGE-----

Two metafication bugs:

First, quite a bit of code (such as zexecve() in exec.c) assumes that
unmetafy() puts a NUL terminator on the string it returns.  I was most
surprised to find that it didn't.  It does now.

Second, filenames generated by globbing, and other code that reads
directories, weren't being metafied, causing all sorts of problems.
Well, actually they *were* being metafied, it's just that the metafied
string was being discarded.  I had to change zreaddir() to return the
filename, rather than the dirent pointer, as the metafied filename might
not fit into the structure.  This simplifies its callers slightly.

There was also one place in zle_tricky.c that was using readdir() instead
of zreaddir().  I guess I must have missed that when I did the big ZLE
8-bit cleanliness patch.

(If you're wondering how I found these bugs: I left the z option off
a tar command line, and it created a file whose name contained several
characters such as \M-^X, which caused mayhem when they got untokenised.
It's a bit disconcerting for "rm <tab><enter>" to fail.)

 -zefram

      Index: Src/glob.c
      ===================================================================
      RCS file: /home/zefram/usr/cvsroot/zsh/Src/glob.c,v
      retrieving revision 1.19
      diff -c -r1.19 glob.c
      *** Src/glob.c	1996/11/08 01:23:06	1.19
      --- Src/glob.c	1996/12/04 00:00:32
      ***************
      *** 1524,1540 ****
        	    /* Do pattern matching on current path section. */
        	    char *fn;
        	    int dirs = !!q->next;
      - 	    struct dirent *de;
        	    DIR *lock = opendir((*pathbuf) ? unmeta(pathbuf) : ".");
        
        	    if (lock == NULL)
        		return;
      ! 	    while ((de = zreaddir(lock))) {
        		/* Loop through the directory */
        		if (errflag)
        		    break;
      - 		/* fn is current file name in directory */
      - 		fn = &de->d_name[0];
        		/* skip this and parent directory */
        		if (fn[0] == '.'
        		    && (fn[1] == '\0'
      --- 1524,1537 ----
        	    /* Do pattern matching on current path section. */
        	    char *fn;
        	    int dirs = !!q->next;
        	    DIR *lock = opendir((*pathbuf) ? unmeta(pathbuf) : ".");
        
        	    if (lock == NULL)
        		return;
      ! 	    while ((fn = zreaddir(lock))) {
        		/* Loop through the directory */
        		if (errflag)
        		    break;
        		/* skip this and parent directory */
        		if (fn[0] == '.'
        		    && (fn[1] == '\0'
      Index: Src/hashtable.c
      ===================================================================
      RCS file: /home/zefram/usr/cvsroot/zsh/Src/hashtable.c,v
      retrieving revision 1.12
      diff -c -r1.12 hashtable.c
      *** Src/hashtable.c	1996/12/01 00:35:13	1.12
      --- Src/hashtable.c	1996/12/04 00:00:59
      ***************
      *** 568,580 ****
        {
            Cmdnam cn;
            DIR *dir;
      !     struct dirent *de;
        
            if (isrelative(*dirp) || !(dir = opendir(unmeta(*dirp))))
        	return;
        
      !     while ((de = zreaddir(dir))) {
      ! 	char *fn = de->d_name;
        	/* Ignore `.' and `..'. */
        	if (fn[0] == '.' &&
        	    (fn[1] == '\0' ||
      --- 568,579 ----
        {
            Cmdnam cn;
            DIR *dir;
      !     char *fn;
        
            if (isrelative(*dirp) || !(dir = opendir(unmeta(*dirp))))
        	return;
        
      !     while ((fn = zreaddir(dir))) {
        	/* Ignore `.' and `..'. */
        	if (fn[0] == '.' &&
        	    (fn[1] == '\0' ||
      Index: Src/utils.c
      ===================================================================
      RCS file: /home/zefram/usr/cvsroot/zsh/Src/utils.c,v
      retrieving revision 1.37
      diff -c -r1.37 utils.c
      *** Src/utils.c	1996/11/21 01:31:18	1.37
      --- Src/utils.c	1996/12/04 00:03:13
      ***************
      *** 658,664 ****
        	    LinkList l;
        	    DIR *lock = opendir(unmeta(*s));
        	    char buf[PATH_MAX * 2], **arr, **ap;
      - 	    struct dirent *de;
        	    int ct = 1;
        
        	    if (lock) {
      --- 658,663 ----
      ***************
      *** 666,675 ****
        		HEAPALLOC {
        		    pushheap();
        		    l = newlinklist();
      ! 		    while ((de = zreaddir(lock))) {
        			if (errflag)
        			    break;
      - 			fn = de->d_name;
        			/* Ignore `.' and `..'. */
        			if (fn[0] == '.' &&
        			    (fn[1] == '\0' ||
      --- 665,673 ----
        		HEAPALLOC {
        		    pushheap();
        		    l = newlinklist();
      ! 		    while ((fn = zreaddir(lock))) {
        			if (errflag)
        			    break;
        			/* Ignore `.' and `..'. */
        			if (fn[0] == '.' &&
        			    (fn[1] == '\0' ||
      ***************
      *** 2618,2624 ****
        {
            int mindistd, nd;
            DIR *dd;
      !     struct dirent *de;
            char buf[PATH_MAX];
        
            if (dir[0] == '\0')
      --- 2616,2622 ----
        {
            int mindistd, nd;
            DIR *dd;
      !     char *fn;
            char buf[PATH_MAX];
        
            if (dir[0] == '\0')
      ***************
      *** 2631,2641 ****
            }
            if (!(dd = opendir(unmeta(dir))))
        	return mindistd;
      !     while ((de = zreaddir(dd))) {
      ! 	nd = spdist(de->d_name, mindistguess,
        		    (int)strlen(mindistguess) / 4 + 1);
        	if (nd <= mindistd) {
      ! 	    strcpy(mindistbest, de->d_name);
        	    mindistd = nd;
        	    if (mindistd == 0)
        		break;
      --- 2629,2639 ----
            }
            if (!(dd = opendir(unmeta(dir))))
        	return mindistd;
      !     while ((fn = zreaddir(dd))) {
      ! 	nd = spdist(fn, mindistguess,
        		    (int)strlen(mindistguess) / 4 + 1);
        	if (nd <= mindistd) {
      ! 	    strcpy(mindistbest, fn);
        	    mindistd = nd;
        	    if (mindistd == 0)
        		break;
      ***************
      *** 2977,2984 ****
            char *p, *t;
        
            for (p = s; *p && *p != Meta; p++);
      !     for (t = p; *p;)
      ! 	if ((*t++ = *p++) == Meta)
        	    t[-1] = *p++ ^ 32;
            if (len)
        	*len = t - s;
      --- 2975,2982 ----
            char *p, *t;
        
            for (p = s; *p && *p != Meta; p++);
      !     for (t = p; (*t = *p++);)
      ! 	if (*t++ == Meta)
        	    t[-1] = *p++ ^ 32;
            if (len)
        	*len = t - s;
      ***************
      *** 3129,3143 ****
        }
        
        /**/
      ! struct dirent *
        zreaddir(DIR *dir)
        {
      !     struct dirent *de;
      ! 
      !     if ((de = readdir(dir)))
      ! 	metafy(de->d_name, -1, META_STATIC);
        
      !     return de;
        }
        
        /* Unmetafy and output a string. */
      --- 3127,3138 ----
        }
        
        /**/
      ! char *
        zreaddir(DIR *dir)
        {
      !     struct dirent *de = readdir(dir);
        
      !     return de ? metafy(de->d_name, -1, META_STATIC) : NULL;
        }
        
        /* Unmetafy and output a string. */
      Index: Src/zle_tricky.c
      ===================================================================
      RCS file: /home/zefram/usr/cvsroot/zsh/Src/zle_tricky.c,v
      retrieving revision 1.50
      diff -c -r1.50 zle_tricky.c
      *** Src/zle_tricky.c	1996/11/24 04:01:33	1.50
      --- Src/zle_tricky.c	1996/12/04 00:05:16
      ***************
      *** 1963,1969 ****
        gen_matches_files(int dirs, int execs, int all)
        {
            DIR *d;
      -     struct dirent *de;
            struct stat buf;
            char *n, p[PATH_MAX], *q = NULL, *e;
            LinkList l = NULL;
      --- 1963,1968 ----
      ***************
      *** 1991,1998 ****
        	    q = p + strlen(prpre);
        	}
        	/* Fine, now read the directory. */
      ! 	while ((de = readdir(d)) && !errflag) {
      ! 	    n = de->d_name;
        	    /* Ignore `.' and `..'. */
        	    if (n[0] == '.' && (n[1] == '\0' || (n[1] == '.' && n[2] == '\0')))
        		continue;
      --- 1990,1996 ----
        	    q = p + strlen(prpre);
        	}
        	/* Fine, now read the directory. */
      ! 	while ((n = zreaddir(d)) && !errflag) {
        	    /* Ignore `.' and `..'. */
        	    if (n[0] == '.' && (n[1] == '\0' || (n[1] == '.' && n[2] == '\0')))
        		continue;

-----BEGIN PGP SIGNATURE-----
Version: 2.6.2

iQCVAwUBMqTDcHD/+HJTpU/hAQEYwwQAsMTO4K1aYMEvBQLOnusZBffatJG/8zWY
KvHPnuxupeNBjJC/Lpcecs7kReQjule5uwNC+gjaTLb6BXAFmDBtiYUAy2/dLmP5
cnXvF4Rm+soFb0R3XUBXGE7MTH4zASztsHp/fCauPcpJEpRvnhDGF5e5pKtjCdJ2
7eNvr8xLJuo=
=BNP7
-----END PGP SIGNATURE-----


                 reply	other threads:[~1996-12-04 10:50 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=26987.199612041028@stone.dcs.warwick.ac.uk \
    --to=zefram@dcs.warwick.ac.uk \
    --cc=zsh-workers@math.gatech.edu \
    /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).