From 91cf9372e89f7af4582964b15ceb7fc6d1b37471 Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Tue, 26 Nov 2019 23:32:31 +0100 Subject: [PATCH] LHA reader: ensure that UTF-16 input always has a multiple of 2 bytes Fixes #1284 --- libarchive/archive_read_support_format_lha.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c index e9d5b83df..dd106909b 100644 --- a/libarchive/archive_read_support_format_lha.c +++ b/libarchive/archive_read_support_format_lha.c @@ -1233,6 +1233,9 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha, /* maybe directory header */ archive_string_empty(&lha->filename); break; + } else if (datasize & 1) { + /* UTF-16 characters take always 2 or 4 bytes */ + goto invalid; } if (extdheader[0] == '\0') goto invalid; @@ -1266,7 +1269,8 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha, goto invalid; break; case EXT_UTF16_DIRECTORY: - if (datasize == 0 || extdheader[0] == '\0') + /* UTF-16 characters take always 2 or 4 bytes */ + if (datasize == 0 || (datasize & 1) || extdheader[0] == '\0') /* no directory name data. exit this case. */ goto invalid; @@ -1277,12 +1281,13 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha, &a->archive, "UTF-16LE", 1); if (lha->sconv_dir == NULL) return (ARCHIVE_FATAL); - /* - * Convert directory delimiter from 0xFF - * to '/' for local system. - */ - { - uint16_t *utf16name = (uint16_t *)lha->dirname.s; /* UTF-16LE character */ + else { + /* + * Convert directory delimiter from 0xFF + * to '/' for local system. + */ + /* UTF-16LE character */ + uint16_t *utf16name = (uint16_t *)lha->dirname.s; for (i = 0; i < lha->dirname.length / 2; i++) { if (utf16name[i] == 0xFFFF) utf16name[i] = L'/'; -- 2.47.2