Date: Mon, 4 Jan 1999 04:20:01 -0800 (PST) From: "Eugene M. Kim" <astralblue@usa.net> To: freebsd-bugs@FreeBSD.ORG Subject: Re: bin/3246: mtree -c should escape whitespace and special characters Message-ID: <199901041220.EAA26989@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/3246; it has been noted by GNATS.
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."
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199901041220.EAA26989>
