diff options
Diffstat (limited to 'libarchive/archive_read_support_format_mtree.c')
-rw-r--r-- | libarchive/archive_read_support_format_mtree.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c index ba0e49de2408..ded13bee79a3 100644 --- a/libarchive/archive_read_support_format_mtree.c +++ b/libarchive/archive_read_support_format_mtree.c @@ -51,6 +51,7 @@ #include "archive.h" #include "archive_entry.h" #include "archive_entry_private.h" +#include "archive_platform_stat.h" #include "archive_private.h" #include "archive_rb.h" #include "archive_read_private.h" @@ -1073,6 +1074,8 @@ read_mtree(struct archive_read *a, struct mtree *mtree) /* Non-printable characters are not allowed */ for (s = p;s < p + len - 1; s++) { if (!isprint((unsigned char)*s) && *s != '\t') { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Non-printable character 0x%02X", (unsigned char)(*s)); r = ARCHIVE_FATAL; break; } @@ -1175,7 +1178,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, struct mtree *mtree, struct mtree_entry *mentry, int *use_next) { const char *path; - struct stat st_storage, *st; + la_seek_stat_t st_storage, *st; struct mtree_entry *mp; struct archive_entry *sparse_entry; int r = ARCHIVE_OK, r1, parsed_kws; @@ -1251,7 +1254,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, archive_entry_filetype(entry) == AE_IFDIR) { mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC); __archive_ensure_cloexec_flag(mtree->fd); - if (mtree->fd == -1 && ( + if (mtree->fd < 0 && ( #if defined(_WIN32) && !defined(__CYGWIN__) /* * On Windows, attempting to open a file with an @@ -1270,7 +1273,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, st = &st_storage; if (mtree->fd >= 0) { - if (fstat(mtree->fd, st) == -1) { + if (la_seek_fstat(mtree->fd, st) == -1) { archive_set_error(&a->archive, errno, "Could not fstat %s", path); r = ARCHIVE_WARN; @@ -1283,7 +1286,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, #ifdef HAVE_LSTAT else if (lstat(path, st) == -1) #else - else if (la_stat(path, st) == -1) + else if (la_seek_stat(path, st) == -1) #endif { st = NULL; @@ -2130,6 +2133,13 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, for (u = mtree->line.s + find_off; *u; ++u) { if (u[0] == '\n') { /* Ends with unescaped newline. */ + /* Check if preceded by '\r' for CRLF handling */ + if (u > mtree->line.s && u[-1] == '\r') { + /* CRLF ending - remove the '\r' */ + u[-1] = '\n'; + u[0] = '\0'; + total_size--; + } *start = mtree->line.s; return total_size; } else if (u[0] == '#') { @@ -2144,6 +2154,11 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, total_size -= 2; mtree->line.s[total_size] = '\0'; break; + } else if (u[1] == '\r' && u[2] == '\n') { + /* Trim escaped CRLF. */ + total_size -= 3; + mtree->line.s[total_size] = '\0'; + break; } else if (u[1] != '\0') { /* Skip the two-char escape sequence */ ++u; |