Skip to content

Commit c04da19

Browse files
authored
Zip entry open/fix 13 (madler#15)
* Internally replace '\' by '/' for entry name. * Add tests
1 parent faf26db commit c04da19

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

src/zip.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,21 @@ static int mkpath(const char *path) {
8282
return 0;
8383
}
8484

85+
static char *strrpl(const char *str, char old, char new) {
86+
char *rpl = (char *)malloc(sizeof(char) * (1 + strlen(str)));
87+
char *begin = rpl;
88+
char c;
89+
while((c = *str++)) {
90+
if (c == old) {
91+
c = new;
92+
}
93+
*rpl++ = c;
94+
}
95+
*rpl = '\0';
96+
97+
return begin;
98+
}
99+
85100
struct zip_entry_t {
86101
int index;
87102
const char *name;
@@ -174,6 +189,7 @@ void zip_close(struct zip_t *zip) {
174189
}
175190

176191
int zip_entry_open(struct zip_t *zip, const char *entryname) {
192+
char *locname = NULL;
177193
size_t entrylen = 0;
178194
mz_zip_archive *pzip = NULL;
179195
mz_uint num_alignment_padding_bytes, level;
@@ -188,14 +204,27 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) {
188204
}
189205

190206
pzip = &(zip->archive);
207+
/*
208+
.ZIP File Format Specification Version: 6.3.3
209+
210+
4.4.17.1 The name of the file, with optional relative path.
211+
The path stored MUST not contain a drive or
212+
device letter, or a leading slash. All slashes
213+
MUST be forward slashes '/' as opposed to
214+
backwards slashes '\' for compatibility with Amiga
215+
and UNIX file systems etc. If input came from standard
216+
input, there is no file name field.
217+
*/
218+
locname = strrpl(entryname, '\\', '/');
191219

192220
if (zip->mode == 'r') {
193-
zip->entry.index = mz_zip_reader_locate_file(pzip, entryname, NULL, 0);
221+
zip->entry.index = mz_zip_reader_locate_file(pzip, locname, NULL, 0);
222+
CLEANUP(locname);
194223
return (zip->entry.index < 0) ? -1 : 0;
195224
}
196225

197226
zip->entry.index = zip->archive.m_total_files;
198-
zip->entry.name = STRCLONE(entryname);
227+
zip->entry.name = locname;
199228
if (!zip->entry.name) {
200229
// Cannot parse zip entry name
201230
return -1;

test/test.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ static void test_write(void) {
1313
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
1414
assert(zip != NULL);
1515

16-
assert(0 == zip_entry_open(zip, "test-1.txt"));
16+
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
1717
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
1818
assert(0 == zip_entry_close(zip));
1919

@@ -24,7 +24,7 @@ static void test_append(void) {
2424
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
2525
assert(zip != NULL);
2626

27-
assert(0 == zip_entry_open(zip, "test-2.txt"));
27+
assert(0 == zip_entry_open(zip, "test\\test-2.txt"));
2828
assert(0 == zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
2929
assert(0 == zip_entry_close(zip));
3030

@@ -37,7 +37,7 @@ static void test_read(void) {
3737
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
3838
assert(zip != NULL);
3939

40-
assert(0 == zip_entry_open(zip, "test-1.txt"));
40+
assert(0 == zip_entry_open(zip, "test\\test-1.txt"));
4141
assert(0 == zip_entry_read(zip, (void **)&buf, &bufsize));
4242
assert(bufsize == strlen(TESTDATA1));
4343
assert(0 == strncmp(buf, TESTDATA1, bufsize));
@@ -46,7 +46,7 @@ static void test_read(void) {
4646
buf = NULL;
4747
bufsize = 0;
4848

49-
assert(0 == zip_entry_open(zip, "test-2.txt"));
49+
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
5050
assert(0 == zip_entry_read(zip, (void **)&buf, &bufsize));
5151
assert(bufsize == strlen(TESTDATA2));
5252
assert(0 == strncmp(buf, TESTDATA2, bufsize));
@@ -82,7 +82,7 @@ static void test_extract(void) {
8282
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
8383
assert(zip != NULL);
8484

85-
assert(0 == zip_entry_open(zip, "test-1.txt"));
85+
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
8686
assert(0 == zip_entry_extract(zip, on_extract, &buf));
8787

8888
assert(buf.size == strlen(TESTDATA1));

0 commit comments

Comments
 (0)