Zip entry open/fix 13 (#15)

* Internally replace '\' by '/' for entry name.

* Add tests
This commit is contained in:
Kuba Podgórski 2017-11-07 16:51:32 +01:00 committed by GitHub
parent faf26db763
commit c04da1926f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 7 deletions

View File

@ -82,6 +82,21 @@ static int mkpath(const char *path) {
return 0;
}
static char *strrpl(const char *str, char old, char new) {
char *rpl = (char *)malloc(sizeof(char) * (1 + strlen(str)));
char *begin = rpl;
char c;
while((c = *str++)) {
if (c == old) {
c = new;
}
*rpl++ = c;
}
*rpl = '\0';
return begin;
}
struct zip_entry_t {
int index;
const char *name;
@ -174,6 +189,7 @@ void zip_close(struct zip_t *zip) {
}
int zip_entry_open(struct zip_t *zip, const char *entryname) {
char *locname = NULL;
size_t entrylen = 0;
mz_zip_archive *pzip = NULL;
mz_uint num_alignment_padding_bytes, level;
@ -188,14 +204,27 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) {
}
pzip = &(zip->archive);
/*
.ZIP File Format Specification Version: 6.3.3
4.4.17.1 The name of the file, with optional relative path.
The path stored MUST not contain a drive or
device letter, or a leading slash. All slashes
MUST be forward slashes '/' as opposed to
backwards slashes '\' for compatibility with Amiga
and UNIX file systems etc. If input came from standard
input, there is no file name field.
*/
locname = strrpl(entryname, '\\', '/');
if (zip->mode == 'r') {
zip->entry.index = mz_zip_reader_locate_file(pzip, entryname, NULL, 0);
zip->entry.index = mz_zip_reader_locate_file(pzip, locname, NULL, 0);
CLEANUP(locname);
return (zip->entry.index < 0) ? -1 : 0;
}
zip->entry.index = zip->archive.m_total_files;
zip->entry.name = STRCLONE(entryname);
zip->entry.name = locname;
if (!zip->entry.name) {
// Cannot parse zip entry name
return -1;

View File

@ -13,7 +13,7 @@ static void test_write(void) {
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, "test-1.txt"));
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
assert(0 == zip_entry_close(zip));
@ -24,7 +24,7 @@ static void test_append(void) {
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, "test-2.txt"));
assert(0 == zip_entry_open(zip, "test\\test-2.txt"));
assert(0 == zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
assert(0 == zip_entry_close(zip));
@ -37,7 +37,7 @@ static void test_read(void) {
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, "test-1.txt"));
assert(0 == zip_entry_open(zip, "test\\test-1.txt"));
assert(0 == zip_entry_read(zip, (void **)&buf, &bufsize));
assert(bufsize == strlen(TESTDATA1));
assert(0 == strncmp(buf, TESTDATA1, bufsize));
@ -46,7 +46,7 @@ static void test_read(void) {
buf = NULL;
bufsize = 0;
assert(0 == zip_entry_open(zip, "test-2.txt"));
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
assert(0 == zip_entry_read(zip, (void **)&buf, &bufsize));
assert(bufsize == strlen(TESTDATA2));
assert(0 == strncmp(buf, TESTDATA2, bufsize));
@ -82,7 +82,7 @@ static void test_extract(void) {
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, "test-1.txt"));
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
assert(0 == zip_entry_extract(zip, on_extract, &buf));
assert(buf.size == strlen(TESTDATA1));