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>