diff options
author | Martin Matuska <martin@matuska.org> | 2019-11-26 23:32:31 +0100 |
---|---|---|
committer | Martin Matuska <martin@matuska.org> | 2019-11-26 23:32:31 +0100 |
commit | 91cf9372e89f7af4582964b15ceb7fc6d1b37471 (patch) | |
tree | 9138dab26727d8e585620ca718daa4847b47d161 /libarchive/archive_read_support_format_lha.c | |
parent | 6b528941eee7935aad7fd3c42b9b9be3ca255b76 (diff) | |
download | libarchive-91cf9372e89f7af4582964b15ceb7fc6d1b37471.tar.gz |
LHA reader: ensure that UTF-16 input always has a multiple of 2 bytes
Fixes #1284
Diffstat (limited to 'libarchive/archive_read_support_format_lha.c')
-rw-r--r-- | libarchive/archive_read_support_format_lha.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c index e9d5b83d..dd106909 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'/'; |