*/
if (archive_entry_filetype(entry) == AE_IFLNK) {
ssize_t bytes;
- const void *p = (const void *)archive_entry_symlink(entry);
+ const void *p = (const void *)archive_entry_symlink_utf8(entry);
bytes = compress_out(a, p, (size_t)file->size, ARCHIVE_Z_RUN);
if (bytes < 0)
return ((int)bytes);
archive_entry_set_size(entry, 0);
if (archive_entry_filetype(entry) == AE_IFDIR)
file->dir = 1;
- else if (archive_entry_filetype(entry) == AE_IFLNK)
- file->size = strlen(archive_entry_symlink(entry));
+ else if (archive_entry_filetype(entry) == AE_IFLNK) {
+ const char* linkpath;
+ linkpath = archive_entry_symlink_utf8(entry);
+ if (linkpath == NULL) {
+ free(file);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "symlink path could not be converted to UTF-8");
+ return (ARCHIVE_FAILED);
+ }
+ else
+ file->size = strlen(linkpath);
+ }
if (archive_entry_mtime_is_set(entry)) {
file->flg |= MTIME_IS_SET;
file->times[MTIME].time = archive_entry_mtime(entry);
--- /dev/null
+/*\r
+ * Copyright (c) 2003-2018\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer\r
+ * in this position and unchanged.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+#include "test.h"\r
+\r
+DEFINE_TEST(test_7zip_filename_encoding_UTF16_win)\r
+{\r
+#if !defined(_WIN32) || defined(__CYGWIN__)\r
+ skipping("This test is meant to verify unicode string handling"\r
+ " on Windows with UTF-16 names");\r
+ return;\r
+#else\r
+ struct archive *a;\r
+ struct archive_entry *entry;\r
+ char buff[4096];\r
+ size_t used;\r
+\r
+ /*\r
+ * Don't call setlocale because we're verifying that the '_w' functions\r
+ * work as expected\r
+ */\r
+\r
+ a = archive_write_new();\r
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_7zip(a));\r
+ assertEqualInt(ARCHIVE_OK,\r
+ archive_write_open_memory(a, buff, sizeof(buff), &used));\r
+\r
+ /* Part 1: file */\r
+ entry = archive_entry_new2(a);\r
+ archive_entry_copy_pathname_w(entry, L"\u8868.txt");\r
+ archive_entry_set_filetype(entry, AE_IFREG);\r
+ archive_entry_set_size(entry, 0);\r
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));\r
+\r
+ /* Part 2: directory */\r
+ archive_entry_clear(entry);\r
+ archive_entry_copy_pathname_w(entry, L"\u8868");\r
+ archive_entry_set_filetype(entry, AE_IFDIR);\r
+ archive_entry_set_size(entry, 0);\r
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));\r
+\r
+ /* Part 3: symlink */\r
+ archive_entry_clear(entry);\r
+ archive_entry_set_pathname(entry, "link.txt");\r
+ archive_entry_copy_symlink_w(entry, L"\u8868.txt");\r
+ archive_entry_set_filetype(entry, AE_IFLNK);\r
+ archive_entry_set_symlink_type(entry, AE_SYMLINK_TYPE_FILE);\r
+ archive_entry_set_size(entry, 0);\r
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));\r
+\r
+ /* NOTE: 7zip does not support hardlinks */\r
+\r
+ archive_entry_free(entry);\r
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));\r
+\r
+ /* Ensure that the archive contents can be read properly */\r
+ /* NOTE: 7zip file contents are not in the order we wrote them! */\r
+ a = archive_read_new();\r
+ archive_read_support_format_all(a);\r
+ archive_read_support_filter_all(a);\r
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7));\r
+\r
+ /* Read part 3: symlink */\r
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));\r
+ assertEqualWString(L"\u8868.txt", archive_entry_symlink_w(entry));\r
+\r
+ /* Read part 1: file */\r
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));\r
+ assertEqualWString(L"\u8868.txt", archive_entry_pathname_w(entry));\r
+\r
+ /* Read part 2: directory */\r
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry));\r
+ /* NOTE: Trailing slash added automatically for us */\r
+ assertEqualWString(L"\u8868/", archive_entry_pathname_w(entry));\r
+\r
+ archive_read_free(a);\r
+#endif\r
+}
\ No newline at end of file