Fixes #16018 by preventing the output of terminal/formatting codes to stdout 
when listing archive content
See https://bugs.busybox.net/show_bug.cgi?id=16018

If stdout is a TTY unsafe chars are replaced with '?':

Before:
$ busybox tar -tf bad.tar
a-totally-innocent-looking-filename.txt

After:
$ ./busybox tar -tf bad.tar
tmp/hidden.txt
?[1A?[1Ka-totally-innocent-looking-filename.txt

The same works for `-v` mode including symlink targets

Added bb_safe_dump_str() to support the above.
---
 archival/libarchive/header_list.c         |  3 ++-
 archival/libarchive/header_verbose_list.c | 14 ++++++------
 include/libbb.h                           | 27 +++++++++++++++++++++++
 3 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/archival/libarchive/header_list.c 
b/archival/libarchive/header_list.c
index 0621aa406..9ee69aae2 100644
--- a/archival/libarchive/header_list.c
+++ b/archival/libarchive/header_list.c
@@ -8,5 +8,6 @@
 void FAST_FUNC header_list(const file_header_t *file_header)
 {
 //TODO: cpio -vp DIR should output "DIR/NAME", not just "NAME" */
-       puts(file_header->name);
+       bb_safe_dump_str(stdout, file_header->name);
+       bb_putchar('\n');
 }
diff --git a/archival/libarchive/header_verbose_list.c 
b/archival/libarchive/header_verbose_list.c
index a575a08a0..956589a1b 100644
--- a/archival/libarchive/header_verbose_list.c
+++ b/archival/libarchive/header_verbose_list.c
@@ -29,7 +29,7 @@ void FAST_FUNC header_verbose_list(const file_header_t 
*file_header)
                /*sprintf(gid, "%u", (unsigned)file_header->gid);*/
                group = utoa(file_header->gid);
        }
-       printf("%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s",
+       printf("%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u ",
                bb_mode_string(modestr, file_header->mode),
                user,
                group,
@@ -39,14 +39,13 @@ void FAST_FUNC header_verbose_list(const file_header_t 
*file_header)
                ptm->tm_mday,
                ptm->tm_hour,
                ptm->tm_min,
-               ptm->tm_sec,
-               file_header->name);
+               ptm->tm_sec);

 #else /* !FEATURE_TAR_UNAME_GNAME */

        localtime_r(&file_header->mtime, ptm);

-       printf("%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s",
+       printf("%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u ",
                bb_mode_string(modestr, file_header->mode),
                (unsigned)file_header->uid,
                (unsigned)file_header->gid,
@@ -56,14 +55,15 @@ void FAST_FUNC header_verbose_list(const file_header_t 
*file_header)
                ptm->tm_mday,
                ptm->tm_hour,
                ptm->tm_min,
-               ptm->tm_sec,
-               file_header->name);
+               ptm->tm_sec);

 #endif /* FEATURE_TAR_UNAME_GNAME */

+       bb_safe_dump_str(stdout, file_header->name);
        /* NB: GNU tar shows "->" for symlinks and "link to" for hardlinks */
        if (file_header->link_target) {
-               printf(" -> %s", file_header->link_target);
+               printf(" -> ");
+               bb_safe_dump_str(stdout, file_header->link_target);
        }
        bb_putchar('\n');
 }
diff --git a/include/libbb.h b/include/libbb.h
index 01cdb1bdc..8d936ccfe 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2524,6 +2524,33 @@ static ALWAYS_INLINE unsigned char 
bb_ascii_tolower(unsigned char a)
 #define isgraph_asciionly(a) ((unsigned)((a) - 0x21) <= 0x7e - 0x21)
 #define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20)

+/* Print msg to a file-descriptor, replacing any terminal control bytes with 
'?' if fd is a TTY */
+static ALWAYS_INLINE void bb_safe_dump_str(FILE* fd, const char* msg) {
+       int fdno = fileno(fd);
+       if (isatty(fdno)) {
+               size_t msg_len = strlen(msg);
+               int i;
+               for (i = 0; i < msg_len; i++) {
+                       switch(msg[i]) {
+                               case 0x08: /* backspace */
+                               case 0x09: /* h-tab */
+                               case 0x0a: /* lf */
+                               case 0x0b: /* v-tab */
+                               case 0x0c: /* ff */
+                               case 0x0d: /* cr */
+                               case 0x1b: /* esc */
+                               case 0x7f: /* del */
+                                       fprintf(fd, "?");
+                                       break;
+                               default:
+                                       fprintf(fd, "%c", msg[i]);
+                                       break;
+                       }
+               }
+       } else {
+               fprintf(fd, "%s", msg);
+       }
+}

 /* Simple unit-testing framework */

--
2.20.1


Any email and files/attachments transmitted with it are intended solely for the 
use of the individual or entity to whom they are addressed. If this message has 
been sent to you in error, you must not copy, distribute or disclose of the 
information it contains. Please notify Entrust immediately and delete the 
message from your system.
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to