diff options
author | Christos Zoulas <christos@zoulas.com> | 2022-05-28 01:04:57 +0000 |
---|---|---|
committer | Christos Zoulas <christos@zoulas.com> | 2022-05-28 01:04:57 +0000 |
commit | f448f3e5c37de8c285ac14b032b2bdcea82fc08b (patch) | |
tree | 6e743807b7579e911fa8ac89bd8a18851dd315dc | |
parent | 850e148d088922878f1e5f6b2e3a9c01f75d21f3 (diff) | |
download | file-git-f448f3e5c37de8c285ac14b032b2bdcea82fc08b.tar.gz |
PR/351: CathyKMeow: octalify unprintable characters in filenames unless raw.
-rw-r--r-- | src/file.c | 46 | ||||
-rw-r--r-- | src/file.h | 4 |
2 files changed, 29 insertions, 21 deletions
@@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: file.c,v 1.193 2022/04/18 21:42:34 christos Exp $") +FILE_RCSID("@(#)$File: file.c,v 1.194 2022/05/28 01:04:57 christos Exp $") #endif /* lint */ #include "magic.h" @@ -57,6 +57,9 @@ FILE_RCSID("@(#)$File: file.c,v 1.193 2022/04/18 21:42:34 christos Exp $") #ifdef HAVE_WCHAR_H #include <wchar.h> #endif +#ifdef HAVE_WCTYPE_H +#include <wctype.h> +#endif #if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION) # include <getopt.h> @@ -413,7 +416,7 @@ main(int argc, char *argv[]) for (wid = 0, j = CAST(size_t, optind); j < CAST(size_t, argc); j++) { - nw = file_mbswidth(argv[j]); + nw = file_mbswidth(magic, argv[j]); if (nw > wid) wid = nw; } @@ -516,7 +519,7 @@ unwrap(struct magic_set *ms, const char *fn) while ((len = getline(&line, &llen, f)) > 0) { if (line[len - 1] == '\n') line[len - 1] = '\0'; - cwid = file_mbswidth(line); + cwid = file_mbswidth(ms, line); if (cwid > wid) wid = cwid; } @@ -544,15 +547,21 @@ process(struct magic_set *ms, const char *inname, int wid) const char *type, c = nulsep > 1 ? '\0' : '\n'; int std_in = strcmp(inname, "-") == 0; int haderror = 0; + size_t plen = 4 * wid + 1; + char *pbuf, *pname; + + if ((pbuf = CAST(char *, malloc(plen))) == NULL) + file_err(EXIT_FAILURE, "Can't allocate %zu bytes", plen); if (wid > 0 && !bflag) { - (void)printf("%s", std_in ? "/dev/stdin" : inname); + pname = file_printable(ms, pbuf, plen, inname, wid); + (void)printf("%s", std_in ? "/dev/stdin" : pname); if (nulsep) (void)putc('\0', stdout); if (nulsep < 2) { (void)printf("%s", separator); (void)printf("%*s ", CAST(int, nopad ? 0 - : (wid - file_mbswidth(inname))), ""); + : (wid - file_mbswidth(ms, inname))), ""); } } @@ -565,14 +574,17 @@ process(struct magic_set *ms, const char *inname, int wid) } if (nobuffer) haderror |= fflush(stdout) != 0; + free(pbuf); return haderror || type == NULL; } protected size_t -file_mbswidth(const char *s) +file_mbswidth(struct magic_set *ms, const char *s) { -#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH) - size_t bytesconsumed, old_n, n, width = 0; + size_t width = 0; +#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH) && \ + defined(HAVE_WCTYPE_H) + size_t bytesconsumed, old_n, n; mbstate_t state; wchar_t nextchar; (void)memset(&state, 0, sizeof(mbstate_t)); @@ -585,22 +597,18 @@ file_mbswidth(const char *s) /* Something went wrong, return something reasonable */ return old_n; } - if (s[0] == '\n') { - /* - * do what strlen() would do, so that caller - * is always right - */ - width++; - } else { - int w = wcwidth(nextchar); - if (w > 0) - width += w; - } + width += ((ms->flags & MAGIC_RAW) != 0 + || iswprint(nextchar)) ? wcwidth(nextchar) : 4; s += bytesconsumed, n -= bytesconsumed; } return width; #else + while (*s) { + width += (ms->flags & MAGIC_RAW) != 0 + || isprint(CAST(unsigned char, *s))) ? 1 : 4; + } + return strlen(s); #endif } @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.232 2022/04/18 21:50:49 christos Exp $ + * @(#)$File: file.h,v 1.233 2022/05/28 01:04:57 christos Exp $ */ #ifndef __file_h__ @@ -565,7 +565,7 @@ protected void file_magwarn(struct magic_set *, const char *, ...) __attribute__((__format__(__printf__, 2, 3))); protected void file_mdump(struct magic *); protected void file_showstr(FILE *, const char *, size_t); -protected size_t file_mbswidth(const char *); +protected size_t file_mbswidth(struct magic_set *, const char *); protected const char *file_getbuffer(struct magic_set *); protected ssize_t sread(int, void *, size_t, int); protected int file_check_mem(struct magic_set *, unsigned int); |