summaryrefslogtreecommitdiff
path: root/libarchive/archive_read_support_format_lha.c
diff options
context:
space:
mode:
authorMartin Matuska <martin@matuska.org>2019-11-26 23:32:31 +0100
committerMartin Matuska <martin@matuska.org>2019-11-26 23:32:31 +0100
commit91cf9372e89f7af4582964b15ceb7fc6d1b37471 (patch)
tree9138dab26727d8e585620ca718daa4847b47d161 /libarchive/archive_read_support_format_lha.c
parent6b528941eee7935aad7fd3c42b9b9be3ca255b76 (diff)
downloadlibarchive-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.c19
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'/';