From eserte@cabulja.herceg.de  Thu Apr 10 04:13:10 1997
Received: from cabulja.herceg.de (cottrell.dialup.fu-berlin.de [160.45.222.107])
          by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id EAA29449
          for <FreeBSD-gnats-submit@freebsd.org>; Thu, 10 Apr 1997 04:13:07 -0700 (PDT)
Received: (from eserte@localhost)
	by cabulja.herceg.de (8.8.5/8.8.5) id MAA00654;
	Thu, 10 Apr 1997 12:25:38 +0200 (CEST)
Message-Id: <199704101025.MAA00654@cabulja.herceg.de>
Date: Thu, 10 Apr 1997 12:25:38 +0200 (CEST)
From: Slaven Rezic <eserte@cs.tu-berlin.de>
Reply-To: eserte@cs.tu-berlin.de
To: freefall-gnats@cabulja.herceg.de
Subject: mtree -c should escape whitespace and special characters
X-Send-Pr-Version: 3.2

>Number:         3246
>Category:       bin
>Synopsis:       mtree -c should escape whitespace and special characters
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 10 04:20:01 PDT 1997
>Closed-Date:    Mon Jan 11 19:00:53 PST 1999
>Last-Modified:  Mon Jan 11 19:02:26 PST 1999
>Originator:     Slaven Rezic
>Release:        FreeBSD 2.2.1-RELEASE i386
>Organization:
Private FreeBSD site, Berlin, Germany
>Environment:

>Description:

	Filenames with whitespace cause problems with mtree -c and a
	subsequent mtree command.

>How-To-Repeat:

	touch "white space"
	mtree -c > /tmp/mtree
	mtree < /tmp/mtree

>Fix:
	
	

>Release-Note:
>Audit-Trail:

From: "Eugene M. Kim" <astralblue@usa.net>
To: freebsd-gnats-submit@freebsd.org, eserte@cs.tu-berlin.de
Cc:  
Subject: Re: bin/3246: mtree -c should escape whitespace and special
 characters
Date: Mon, 4 Jan 1999 04:10:59 -0800 (PST)

 The following patch fixes the problem by escaping unprintable and
 whitespace characters in URL-encoding style.  For example, the name "I
 have spaces" will be encoded as "I%20have%20spaces".
 
 Note that this might raise an incompatibility issue if any preexisting
 mtree spec file has a filename with a `%' character followed by two
 hexadecimal characters, because that would be recognized as a escape
 sequence by the new mtree program.  (As far as I know, the core FreeBSD
 part doesn't use mtree in such a way.)
 
 ------------------------------- cut here -------------------------------
 diff -cbrN src/usr.sbin/mtree/Makefile src/usr.sbin/mtree.new/Makefile
 *** src/usr.sbin/mtree/Makefile	Sat Feb 22 08:07:51 1997
 --- src/usr.sbin/mtree.new/Makefile	Mon Jan  4 02:37:05 1999
 ***************
 *** 2,8 ****
   #	$Id: Makefile,v 1.6 1997/02/22 16:07:51 peter Exp $
   
   PROG=	mtree
 ! SRCS=	compare.c crc.c create.c misc.c mtree.c spec.c verify.c
   MAN8=	mtree.8
   .PATH:	${.CURDIR}/../../usr.bin/cksum
   
 --- 2,8 ----
   #	$Id: Makefile,v 1.6 1997/02/22 16:07:51 peter Exp $
   
   PROG=	mtree
 ! SRCS=	compare.c crc.c create.c misc.c mtree.c spec.c verify.c escape.c
   MAN8=	mtree.8
   .PATH:	${.CURDIR}/../../usr.bin/cksum
   
 diff -cbrN src/usr.sbin/mtree/create.c src/usr.sbin/mtree.new/create.c
 *** src/usr.sbin/mtree/create.c	Sun Aug  2 07:41:34 1998
 --- src/usr.sbin/mtree.new/create.c	Mon Jan  4 02:51:23 1999
 ***************
 *** 138,148 ****
   	struct passwd *pw;
   	u_long len, val;
   	int fd, offset;
   
   	if (iflag || S_ISDIR(p->fts_statp->st_mode))
 ! 		offset = printf("%*s%s", indent, "", p->fts_name);
   	else
 ! 		offset = printf("%*s    %s", indent, "", p->fts_name);
   
   	if (offset > (INDENTNAMELEN + indent))
   		offset = MAXLINELEN;
 --- 138,156 ----
   	struct passwd *pw;
   	u_long len, val;
   	int fd, offset;
 + 	char *escaped_name;
 + 
 + 	escaped_name = calloc(1, escaped_len(p->fts_name) + 1);
 + 	if (!escaped_name)
 + 	  errx(1, "statf(): calloc() failed");
 + 	escape(p->fts_name, escaped_name);
   
   	if (iflag || S_ISDIR(p->fts_statp->st_mode))
 ! 		offset = printf("%*s%s", indent, "", escaped_name);
   	else
 ! 		offset = printf("%*s    %s", indent, "", escaped_name);
 ! 	
 ! 	free(escaped_name);
   
   	if (offset > (INDENTNAMELEN + indent))
   		offset = MAXLINELEN;
 diff -cbrN src/usr.sbin/mtree/escape.c src/usr.sbin/mtree.new/escape.c
 *** src/usr.sbin/mtree/escape.c	Wed Dec 31 16:00:00 1969
 --- src/usr.sbin/mtree.new/escape.c	Mon Jan  4 03:46:54 1999
 ***************
 *** 0 ****
 --- 1,65 ----
 + #include <string.h>
 + #include <ctype.h>
 + 
 + size_t
 + escaped_len
 + (char const *s)
 + {
 + 	size_t ret;
 + 	char const *p;
 + 	for (p = s, ret = 0; *p != '\0'; p++, ret++) {
 + 		if (!isprint(*p) || isspace(*p) || *p == '%')
 + 			ret += 2;
 + 	}
 + 	return ret;
 + }
 + 
 + void
 + escape
 + (char const *s, char *d)
 + {
 + 	char const *ps;
 + 	char *pd;
 + 	for (ps = s, pd = d; *ps != '\0'; ps++) {
 + 		if (!isprint(*ps) || isspace(*ps) || *ps == '%') {
 + 			char c;
 + 			*pd++ = '%';
 + 			c = (*ps >> 4) & 0xf; *pd++ = (c >= 10) ? 'A' + c - 10 : '0' + c;
 + 			c =  *ps       & 0xf; *pd++ = (c >= 10) ? 'A' + c - 10 : '0' + c;
 + 		} else
 + 			*pd++ = *ps;
 + 	}
 + }
 + 
 + size_t
 + unescaped_len
 + (char const *s)
 + {
 + 	size_t ret;
 + 	char const *ps;
 + 	for (ps = s, ret = 0; *ps != '\0'; ps++, ret++) {
 + 		if (*ps == '%' && isxdigit(ps[1]) && isxdigit(ps[2]))
 + 			ps += 2;
 + 	}
 + 	return ret;
 + }
 + 
 + void
 + unescape
 + (char const *s, char *d)
 + {
 + 	char const *ps;
 + 	char *pd;
 + 
 + 	for (ps = s, pd = d; *ps != '\0'; ps++) {
 + 		if (*ps == '%' && isxdigit(ps[1]) && isxdigit(ps[2])) {
 + 			char c;
 + 			c  = isalpha(ps[1]) ? toupper(ps[1]) - 'A' + 10 : ps[1] - '0';
 + 			c <<= 4;
 + 			c |= isalpha(ps[2]) ? toupper(ps[2]) - 'A' + 10 : ps[2] - '0';
 + 			*pd++ = c;
 + 			ps += 2;
 + 		} else
 + 			*pd++ = *ps;
 + 	}
 + }
 diff -cbrN src/usr.sbin/mtree/escape.h src/usr.sbin/mtree.new/escape.h
 *** src/usr.sbin/mtree/escape.h	Wed Dec 31 16:00:00 1969
 --- src/usr.sbin/mtree.new/escape.h	Mon Jan  4 02:25:51 1999
 ***************
 *** 0 ****
 --- 1,11 ----
 + #ifndef ESCAPE_H__
 + #define ESCAPE_H__
 + 
 + #include <stddef.h>
 + 
 + size_t	escaped_len __P((char const *s));
 + void	escape __P((char const *s, char *d));
 + size_t	unescaped_len __P((char const *s));
 + void	unescape __P((char const *s, char *d));
 + 
 + #endif /* ESCAPE_H__ */
 diff -cbrN src/usr.sbin/mtree/spec.c src/usr.sbin/mtree.new/spec.c
 *** src/usr.sbin/mtree/spec.c	Tue Dec 15 20:54:08 1998
 --- src/usr.sbin/mtree.new/spec.c	Mon Jan  4 02:36:24 1999
 ***************
 *** 140,152 ****
   noparent:		errx(1, "line %d: no parent node", lineno);
   		}
   
 ! 		if ((centry = calloc(1, sizeof(NODE) + strlen(p))) == NULL)
   			errx(1, "calloc");
   		*centry = ginfo;
 - 		(void)strcpy(centry->name, p);
   #define	MAGIC	"?*["
   		if (strpbrk(p, MAGIC))
   			centry->flags |= F_MAGIC;
   		set(NULL, centry);
   
   		if (!root) {
 --- 140,152 ----
   noparent:		errx(1, "line %d: no parent node", lineno);
   		}
   
 ! 		if ((centry = calloc(1, sizeof(NODE) + unescaped_len(p))) == NULL)
   			errx(1, "calloc");
   		*centry = ginfo;
   #define	MAGIC	"?*["
   		if (strpbrk(p, MAGIC))
   			centry->flags |= F_MAGIC;
 + 		unescape(p, centry->name);
   		set(NULL, centry);
   
   		if (!root) {
 ------------------------------- cut here -------------------------------
 
 Eugene M. Kim <astralblue@usa.net>
 
 "Is your music unpopular?  Make it popular; make music
 which people like, or make people who like your music."
 

From: Joseph Koshy <jkoshy>
To: Slaven Rezic <eserte@cs.tu-berlin.de>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/3246: mtree -c should escape whitespace and special characters
Date: Tue, 5 Jan 1999 21:08:11 -0800 (PST)

 I was looking at your PR with the intent of committing the patches.
 I have a few points:
 
 1.	new file `escape.c'
 
 	- needs a copyright (you could copy the copyright from the other
 	  files).  Alternatively you could fold the code into an
 	  existing file like `misc.c'.
 
 	- needs to follow the same source style as the rest of mtree
 	  (see style(9) for hints)
 
 	The same comments apply to "escape.h" too.
 
 2.	Rather than have to call 'escaped_len()' and 'unescaped_len()'
 	can then allocate the required space, how about making the
 	`escape()' and `unescape()' functions do the space allocation
 	transparently?  This allows the caller to just call `escape' 
 	or `unescape()' and free the returned pointer when done.
 
 3.	In 'spec.c', you are calloc()ing as follows:
 
 --- 140,152 ----
 noparent:		errx(1, "line %d: no parent node", lineno);
    		}
    
 !		if ((centry = calloc(1, sizeof(NODE) + unescaped_len(p))) == NULL)
    			errx(1, "calloc");
    		*centry = ginfo;
 
 	This doesn't seem to leave space for the last '0'?   The original
 	code also has this buglet.
 
 If you could correct the above and submit the new patches as a
 followup to this PR, it would be great.  
 
 Thanks,
 Koshy
 <jkoshy@freebsd.org>
 
 

From: Slaven Rezic <eserte@cs.tu-berlin.de>
To: Joseph Koshy <jkoshy@FreeBSD.ORG>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/3246: mtree -c should escape whitespace and special characters
Date: 06 Jan 1999 11:09:54 +0100

 Joseph Koshy <jkoshy@FreeBSD.ORG> writes:
 
 > 
 > 
 > 
 > I was looking at your PR with the intent of committing the patches.
 > I have a few points:
 > 
 > 1.	new file `escape.c'
 > 
 > 	- needs a copyright (you could copy the copyright from the other
 > 	  files).  Alternatively you could fold the code into an
 > 	  existing file like `misc.c'.
 > 
 > 	- needs to follow the same source style as the rest of mtree
 > 	  (see style(9) for hints)
 > 
 > 	The same comments apply to "escape.h" too.
 > 
 > 2.	Rather than have to call 'escaped_len()' and 'unescaped_len()'
 > 	can then allocate the required space, how about making the
 > 	`escape()' and `unescape()' functions do the space allocation
 > 	transparently?  This allows the caller to just call `escape' 
 > 	or `unescape()' and free the returned pointer when done.
 > 
 > 3.	In 'spec.c', you are calloc()ing as follows:
 > 
 > --- 140,152 ----
 > noparent:		errx(1, "line %d: no parent node", lineno);
 >    		}
 >    
 > !		if ((centry = calloc(1, sizeof(NODE) + unescaped_len(p))) == NULL)
 >    			errx(1, "calloc");
 >    		*centry = ginfo;
 > 
 > 	This doesn't seem to leave space for the last '0'?   The original
 > 	code also has this buglet.
 > 
 > If you could correct the above and submit the new patches as a
 > followup to this PR, it would be great.  
 
 Please note that Eugene M. Kim <astralblue@usa.net> is the author of
 the patch, not me. I'd sent a forward of your mail to him.
 
 Regards,
 	Slaven
 
 -- 
 use Tk;$c=tkinit->Canvas->pack;$x=45;for(split/_/,'KPI1_+09IPK_K;-OA1_+K!;A__1;
 Q!7G_1+QK_3CLPI90,_+K!;A_+1!KQ!.N_K+1Q!.F_1+KN.Q__1+KN._K+1Q!.F_1+KN.Q_+1Q__+1!
 KQ!.N_1;Q!7G_K3,09Q_+1!K.Q_K+1Q!.F_1+KN.Q'){s/\n//g;for(split/!/){$c->create(
 'line',map{$a=-43+ord;($x+($a>>3)*2,123+($a&7)*2)}split//)}$x+=12}MainLoop
 
State-Changed-From-To: open->closed 
State-Changed-By: jkoshy 
State-Changed-When: Mon Jan 11 19:00:53 PST 1999 
State-Changed-Why:  
Revised patch committed in rev 1.9 of "src/usr.sbin/mtree/spec.c" and 
in rev 1.12 of "src/usr.sbin/mtree/create.c", thanks! 
>Unformatted:
