Skip to content

Commit 8f897f1

Browse files
committed
Replace deprecated libzip functions
We replace all deprecated libzip functions with their recommended substitutes, and add proper comment length checks including a test case.
1 parent 5703943 commit 8f897f1

File tree

3 files changed

+87
-25
lines changed

3 files changed

+87
-25
lines changed

ext/zip/php_zip.c

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ static int le_zip_entry;
8080
#define PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) \
8181
if (comment_len == 0) { \
8282
/* Passing NULL remove the existing comment */ \
83-
if (zip_set_file_comment(za, index, NULL, 0) < 0) { \
83+
if (zip_file_set_comment(za, index, NULL, 0, 0) < 0) { \
8484
RETURN_FALSE; \
8585
} \
86-
} else if (zip_set_file_comment(za, index, comment, comment_len) < 0) { \
86+
} else if (zip_file_set_comment(za, index, comment, comment_len, 0) < 0) { \
8787
RETURN_FALSE; \
8888
} \
8989
RETURN_TRUE;
@@ -408,7 +408,7 @@ static int php_zip_parse_options(zval *options, zend_long *remove_all_path, char
408408
#endif
409409
/* }}} */
410410

411-
static int php_zip_status(struct zip *za) /* {{{ */
411+
static zend_long php_zip_status(struct zip *za) /* {{{ */
412412
{
413413
#if LIBZIP_VERSION_MAJOR < 1
414414
int zep, syp;
@@ -426,7 +426,7 @@ static int php_zip_status(struct zip *za) /* {{{ */
426426
}
427427
/* }}} */
428428

429-
static int php_zip_status_sys(struct zip *za) /* {{{ */
429+
static zend_long php_zip_status_sys(struct zip *za) /* {{{ */
430430
{
431431
#if LIBZIP_VERSION_MAJOR < 1
432432
int zep, syp;
@@ -444,9 +444,10 @@ static int php_zip_status_sys(struct zip *za) /* {{{ */
444444
}
445445
/* }}} */
446446

447-
static int php_zip_get_num_files(struct zip *za) /* {{{ */
447+
static zend_long php_zip_get_num_files(struct zip *za) /* {{{ */
448448
{
449-
return zip_get_num_files(za);
449+
zip_int64_t num = zip_get_num_entries(za, 0);
450+
return MIN(num, ZEND_LONG_MAX);
450451
}
451452
/* }}} */
452453

@@ -784,7 +785,7 @@ static zend_object_handlers zip_object_handlers;
784785

785786
static HashTable zip_prop_handlers;
786787

787-
typedef int (*zip_read_int_t)(struct zip *za);
788+
typedef zend_long (*zip_read_int_t)(struct zip *za);
788789
typedef char *(*zip_read_const_char_t)(struct zip *za, int *len);
789790
typedef char *(*zip_read_const_char_from_ze_t)(ze_zip_object *obj);
790791

@@ -1177,7 +1178,7 @@ static PHP_NAMED_FUNCTION(zif_zip_open)
11771178
}
11781179

11791180
rsrc_int->index_current = 0;
1180-
rsrc_int->num_files = zip_get_num_files(rsrc_int->za);
1181+
rsrc_int->num_files = zip_get_num_entries(rsrc_int->za, 0);
11811182

11821183
RETURN_RES(zend_register_resource(rsrc_int, le_zip_dir));
11831184
}
@@ -1553,10 +1554,12 @@ static ZIPARCHIVE_METHOD(count)
15531554
{
15541555
struct zip *intern;
15551556
zval *self = ZEND_THIS;
1557+
zip_int64_t num;
15561558

15571559
ZIP_FROM_OBJECT(intern, self);
15581560

1559-
RETVAL_LONG(zip_get_num_files(intern));
1561+
num = zip_get_num_entries(intern, 0);
1562+
RETVAL_LONG(MIN(num, ZEND_LONG_MAX));
15601563
}
15611564
/* }}} */
15621565

@@ -1840,7 +1843,7 @@ static ZIPARCHIVE_METHOD(addFromString)
18401843
}
18411844
}
18421845

1843-
if (zip_add(intern, name, zs) == -1) {
1846+
if (zip_file_add(intern, name, zs, 0) == -1) {
18441847
zip_source_free(zs);
18451848
RETURN_FALSE;
18461849
} else {
@@ -1966,7 +1969,13 @@ static ZIPARCHIVE_METHOD(setArchiveComment)
19661969
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &comment, &comment_len) == FAILURE) {
19671970
return;
19681971
}
1969-
if (zip_set_archive_comment(intern, (const char *)comment, (int)comment_len)) {
1972+
1973+
if (comment_len > 0xffff) {
1974+
php_error_docref(NULL, E_WARNING, "Comment must not exceed 65535 bytes");
1975+
RETURN_FALSE;
1976+
}
1977+
1978+
if (zip_set_archive_comment(intern, (const char *)comment, comment_len)) {
19701979
RETURN_FALSE;
19711980
} else {
19721981
RETURN_TRUE;
@@ -2019,6 +2028,11 @@ static ZIPARCHIVE_METHOD(setCommentName)
20192028
php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
20202029
}
20212030

2031+
if (comment_len > 0xffff) {
2032+
php_error_docref(NULL, E_WARNING, "Comment must not exceed 65535 bytes");
2033+
RETURN_FALSE;
2034+
}
2035+
20222036
idx = zip_name_locate(intern, name, 0);
20232037
if (idx < 0) {
20242038
RETURN_FALSE;
@@ -2045,6 +2059,11 @@ static ZIPARCHIVE_METHOD(setCommentIndex)
20452059
return;
20462060
}
20472061

2062+
if (comment_len > 0xffff) {
2063+
php_error_docref(NULL, E_WARNING, "Comment must not exceed 65535 bytes");
2064+
RETURN_FALSE;
2065+
}
2066+
20482067
PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
20492068
PHP_ZIP_SET_FILE_COMMENT(intern, index, comment, comment_len);
20502069
}
@@ -2249,7 +2268,7 @@ static ZIPARCHIVE_METHOD(getCommentName)
22492268
size_t name_len;
22502269
int idx;
22512270
zend_long flags = 0;
2252-
int comment_len = 0;
2271+
zip_uint32_t comment_len = 0;
22532272
const char * comment;
22542273
char *name;
22552274

@@ -2269,8 +2288,8 @@ static ZIPARCHIVE_METHOD(getCommentName)
22692288
RETURN_FALSE;
22702289
}
22712290

2272-
comment = zip_get_file_comment(intern, idx, &comment_len, (int)flags);
2273-
RETURN_STRINGL((char *)comment, (zend_long)comment_len);
2291+
comment = zip_file_get_comment(intern, idx, &comment_len, (zip_flags_t)flags);
2292+
RETURN_STRINGL((char *)comment, comment_len);
22742293
}
22752294
/* }}} */
22762295

@@ -2282,7 +2301,7 @@ static ZIPARCHIVE_METHOD(getCommentIndex)
22822301
zval *self = ZEND_THIS;
22832302
zend_long index, flags = 0;
22842303
const char * comment;
2285-
int comment_len = 0;
2304+
zip_uint32_t comment_len = 0;
22862305
struct zip_stat sb;
22872306

22882307
ZIP_FROM_OBJECT(intern, self);
@@ -2293,8 +2312,8 @@ static ZIPARCHIVE_METHOD(getCommentIndex)
22932312
}
22942313

22952314
PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
2296-
comment = zip_get_file_comment(intern, index, &comment_len, (int)flags);
2297-
RETURN_STRINGL((char *)comment, (zend_long)comment_len);
2315+
comment = zip_file_get_comment(intern, index, &comment_len, (zip_flags_t)flags);
2316+
RETURN_STRINGL((char *)comment, comment_len);
22982317
}
22992318
/* }}} */
23002319

@@ -2435,7 +2454,7 @@ static ZIPARCHIVE_METHOD(renameIndex)
24352454
php_error_docref(NULL, E_NOTICE, "Empty string as new entry name");
24362455
RETURN_FALSE;
24372456
}
2438-
if (zip_rename(intern, index, (const char *)new_name) != 0) {
2457+
if (zip_file_rename(intern, index, (const char *)new_name, 0) != 0) {
24392458
RETURN_FALSE;
24402459
}
24412460
RETURN_TRUE;
@@ -2465,7 +2484,7 @@ static ZIPARCHIVE_METHOD(renameName)
24652484

24662485
PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
24672486

2468-
if (zip_rename(intern, sb.index, (const char *)new_name)) {
2487+
if (zip_file_rename(intern, sb.index, (const char *)new_name, 0)) {
24692488
RETURN_FALSE;
24702489
}
24712490
RETURN_TRUE;
@@ -2579,9 +2598,7 @@ static ZIPARCHIVE_METHOD(extractTo)
25792598
php_stream_statbuf ssb;
25802599
char *pathto;
25812600
size_t pathto_len;
2582-
int ret, i;
2583-
2584-
int nelems;
2601+
int ret;
25852602

25862603
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|z", &pathto, &pathto_len, &zval_files) == FAILURE) {
25872604
return;
@@ -2600,6 +2617,8 @@ static ZIPARCHIVE_METHOD(extractTo)
26002617

26012618
ZIP_FROM_OBJECT(intern, self);
26022619
if (zval_files && (Z_TYPE_P(zval_files) != IS_NULL)) {
2620+
uint32_t nelems, i;
2621+
26032622
switch (Z_TYPE_P(zval_files)) {
26042623
case IS_STRING:
26052624
if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_files), Z_STRLEN_P(zval_files))) {
@@ -2632,7 +2651,7 @@ static ZIPARCHIVE_METHOD(extractTo)
26322651
}
26332652
} else {
26342653
/* Extract all files */
2635-
int filecount = zip_get_num_files(intern);
2654+
zip_int64_t i, filecount = zip_get_num_entries(intern, 0);
26362655

26372656
if (filecount == -1) {
26382657
php_error_docref(NULL, E_WARNING, "Illegal archive");

ext/zip/php_zip.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ extern zend_module_entry zip_module_entry;
3939

4040
typedef struct _ze_zip_rsrc {
4141
struct zip *za;
42-
int index_current;
43-
int num_files;
42+
zip_uint64_t index_current;
43+
zip_int64_t num_files;
4444
} zip_rsrc;
4545

4646
typedef zip_rsrc * zip_rsrc_ptr;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
setComment error behavior
3+
--SKIPIF--
4+
<?php
5+
if(!extension_loaded('zip')) die('skip zip extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
$file = __DIR__ . '/__tmp_oo_set_comment_error.zip';
10+
11+
@unlink($file);
12+
13+
$zip = new ZipArchive;
14+
if (!$zip->open($file, ZIPARCHIVE::CREATE)) {
15+
exit('failed');
16+
}
17+
18+
$zip->addFromString('entry1.txt', 'entry #1');
19+
$zip->addFromString('entry2.txt', 'entry #2');
20+
21+
$longComment = str_repeat('a', 0x10000);
22+
23+
var_dump($zip->setArchiveComment($longComment));
24+
var_dump($zip->setCommentName('entry1.txt', $longComment));
25+
var_dump($zip->setCommentIndex(1, $longComment));
26+
27+
$zip->close();
28+
?>
29+
===DONE===
30+
--EXPECTF--
31+
Warning: ZipArchive::setArchiveComment(): Comment must not exceed 65535 bytes in %s on line %d
32+
bool(false)
33+
34+
Warning: ZipArchive::setCommentName(): Comment must not exceed 65535 bytes in %s on line %d
35+
bool(false)
36+
37+
Warning: ZipArchive::setCommentIndex(): Comment must not exceed 65535 bytes in %s on line %d
38+
bool(false)
39+
===DONE===
40+
--CLEAN--
41+
<?php
42+
@unlink(__DIR__ . '/__tmp_oo_set_comment_error.zip');
43+
?>

0 commit comments

Comments
 (0)