summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2008-03-14 23:19:46 +0000
committerkientzle <kientzle@FreeBSD.org>2008-03-14 23:19:46 +0000
commitf5ba8800a4c9aebe0cf016e53ef3ad6d33c4cedd (patch)
treea273427a8f96186a63e2a54d839101c418433aa8 /lib
parent794d55fb646e76a8a8b08772271e57658e865df4 (diff)
downloadFreeBSD-src-f5ba8800a4c9aebe0cf016e53ef3ad6d33c4cedd.zip
FreeBSD-src-f5ba8800a4c9aebe0cf016e53ef3ad6d33c4cedd.tar.gz
Don't lie. If a string can't be converted to a wide (Unicode) string,
return a NULL instead of an incomplete string. Expand the test coverage to verify the correct behavior here.
Diffstat (limited to 'lib')
-rw-r--r--lib/libarchive/archive_entry.c9
-rw-r--r--lib/libarchive/test/test_entry.c35
2 files changed, 43 insertions, 1 deletions
diff --git a/lib/libarchive/archive_entry.c b/lib/libarchive/archive_entry.c
index 8fbc0ac..8da0215 100644
--- a/lib/libarchive/archive_entry.c
+++ b/lib/libarchive/archive_entry.c
@@ -207,6 +207,8 @@ aes_get_mbs(struct aes *aes)
static const wchar_t *
aes_get_wcs(struct aes *aes)
{
+ int r;
+
if (aes->aes_wcs == NULL && aes->aes_mbs == NULL)
return NULL;
if (aes->aes_wcs == NULL && aes->aes_mbs != NULL) {
@@ -221,8 +223,13 @@ aes_get_wcs(struct aes *aes)
aes->aes_wcs = aes->aes_wcs_alloc;
if (aes->aes_wcs == NULL)
__archive_errx(1, "No memory for aes_get_wcs()");
- mbstowcs(aes->aes_wcs_alloc, aes->aes_mbs, wcs_length);
+ r = mbstowcs(aes->aes_wcs_alloc, aes->aes_mbs, wcs_length);
aes->aes_wcs_alloc[wcs_length] = 0;
+ if (r == -1) {
+ /* Conversion failed, don't lie to our clients. */
+ free(aes->aes_wcs_alloc);
+ aes->aes_wcs = aes->aes_wcs_alloc = NULL;
+ }
}
return (aes->aes_wcs);
}
diff --git a/lib/libarchive/test/test_entry.c b/lib/libarchive/test/test_entry.c
index 3fd1d06..638af48 100644
--- a/lib/libarchive/test/test_entry.c
+++ b/lib/libarchive/test/test_entry.c
@@ -25,6 +25,8 @@
#include "test.h"
__FBSDID("$FreeBSD$");
+#include <locale.h>
+
/*
* Most of these tests are system-independent, though a few depend on
* features of the local system. Such tests are conditionalized on
@@ -721,6 +723,39 @@ DEFINE_TEST(test_entry)
#endif
#endif
+ /*
+ * Exercise the character-conversion logic, if we can.
+ */
+ failure("Can't exercise charset-conversion logic.");
+ if (assert(NULL != setlocale(LC_ALL, "de_DE.UTF-8"))) {
+ /* A filename that cannot be converted to wide characters. */
+ archive_entry_copy_pathname(e, "abc\314\214mno\374xyz");
+ failure("Converting invalid chars to Unicode should fail.");
+ assert(NULL == archive_entry_pathname_w(e));
+ //failure("Converting invalid chars to UTF-8 should fail.");
+ //assert(NULL == archive_entry_pathname_utf8(e));
+
+ /* A group name that cannot be converted. */
+ archive_entry_copy_gname(e, "abc\314\214mno\374xyz");
+ failure("Converting invalid chars to Unicode should fail.");
+ assert(NULL == archive_entry_gname_w(e));
+
+ /* A user name that cannot be converted. */
+ archive_entry_copy_uname(e, "abc\314\214mno\374xyz");
+ failure("Converting invalid chars to Unicode should fail.");
+ assert(NULL == archive_entry_uname_w(e));
+
+ /* A hardlink target that cannot be converted. */
+ archive_entry_copy_hardlink(e, "abc\314\214mno\374xyz");
+ failure("Converting invalid chars to Unicode should fail.");
+ assert(NULL == archive_entry_hardlink_w(e));
+
+ /* A symlink target that cannot be converted. */
+ archive_entry_copy_symlink(e, "abc\314\214mno\374xyz");
+ failure("Converting invalid chars to Unicode should fail.");
+ assert(NULL == archive_entry_symlink_w(e));
+ }
+
/* Release the experimental entry. */
archive_entry_free(e);
}
OpenPOWER on IntegriCloud