Blob Blame History Raw
From 42a3408ac7df1e69bea9ea12b72e14f59f7400c0 Mon Sep 17 00:00:00 2001
From: Martin Matuska <martin@matuska.org>
Date: Mon, 26 Dec 2016 22:23:24 +0100
Subject: [PATCH] archive_strncat_l(): allocate and do not convert if length ==
 0

This ensures e.g. that archive_mstring_copy_mbs_len_l() does not set
aes_set = AES_SET_MBS with aes_mbs.s == NULL.

Resolves possible null-pointer dereference reported by OSS-Fuzz.

Reported-By:	OSS-Fuzz issue 286
---
 libarchive/archive_string.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
index 645570b..bbb1e45 100644
--- a/libarchive/archive_string.c
+++ b/libarchive/archive_string.c
@@ -1939,12 +1939,19 @@ archive_strncat_l(struct archive_string *as, const void *_p, size_t n,
     struct archive_string_conv *sc)
 {
 	const void *s;
-	size_t length;
+	size_t length = 0;
 	int i, r = 0, r2;
 
+	if (_p != NULL && n > 0) {
+		if (sc != NULL && (sc->flag & SCONV_FROM_UTF16))
+			length = utf16nbytes(_p, n);
+		else
+			length = mbsnbytes(_p, n);
+	}
+
 	/* We must allocate memory even if there is no data for conversion
 	 * or copy. This simulates archive_string_append behavior. */
-	if (_p == NULL || n == 0) {
+	if (length == 0) {
 		int tn = 1;
 		if (sc != NULL && (sc->flag & SCONV_TO_UTF16))
 			tn = 2;
@@ -1960,16 +1967,11 @@ archive_strncat_l(struct archive_string *as, const void *_p, size_t n,
 	 * If sc is NULL, we just make a copy.
 	 */
 	if (sc == NULL) {
-		length = mbsnbytes(_p, n);
 		if (archive_string_append(as, _p, length) == NULL)
 			return (-1);/* No memory */
 		return (0);
 	}
 
-	if (sc->flag & SCONV_FROM_UTF16)
-		length = utf16nbytes(_p, n);
-	else
-		length = mbsnbytes(_p, n);
 	s = _p;
 	i = 0;
 	if (sc->nconverter > 1) {