Skip to content

Commit 6f53605

Browse files
committed
- make status, statusSys properties and
ZipArchive::getStatusString() method available after archive is closed
1 parent 32c2ae2 commit 6f53605

File tree

6 files changed

+84
-40
lines changed

6 files changed

+84
-40
lines changed

NEWS

+5-2
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,10 @@ PHP NEWS
139139
addFromString methods. (Remi)
140140
. Add "flags" options to ZipArchive::addGlob and addPattern methods
141141
keeping previous behavior having FL_OVERWRITE by default. (Remi)
142-
. Add ZipArchive::replaceFile() method
143-
. Add lastId property to ZipArchive
142+
. Add ZipArchive::replaceFile() method. (Remi)
143+
. Add lastId property to ZipArchive. (Remi)
144+
. ZipArchive::status and ZipArchive::statusSys properties and
145+
ZipArchive::getStatusString() method stay valid after the archive
146+
is closed. (Remi)
144147

145148
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>

ext/zip/php_zip.c

+71-36
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ static int php_zip_add_file(ze_zip_object *obj, const char *filename, size_t fil
304304
if (!zs) {
305305
return -1;
306306
}
307-
// Replace
307+
/* Replace */
308308
if (replace >= 0) {
309309
if (zip_file_replace(obj->za, replace, zs, flags) < 0) {
310310
zip_source_free(zs);
@@ -313,7 +313,7 @@ static int php_zip_add_file(ze_zip_object *obj, const char *filename, size_t fil
313313
zip_error_clear(obj->za);
314314
return 1;
315315
}
316-
// Add
316+
/* Add */
317317
obj->last_id = zip_file_add(obj->za, entry_name, zs, flags);
318318
if (obj->last_id < 0) {
319319
zip_source_free(zs);
@@ -436,18 +436,21 @@ static int php_zip_parse_options(zval *options, zend_long *remove_all_path,
436436

437437
static zend_long php_zip_status(ze_zip_object *obj) /* {{{ */
438438
{
439+
int zep = obj->err_zip; /* saved err if closed */
440+
441+
if (obj->za) {
439442
#if LIBZIP_VERSION_MAJOR < 1
440-
int zep, syp;
443+
int syp;
441444

442-
zip_error_get(obj->za, &zep, &syp);
445+
zip_error_get(obj->za, &zep, &syp);
443446
#else
444-
int zep;
445-
zip_error_t *err;
447+
zip_error_t *err;
446448

447-
err = zip_get_error(obj->za);
448-
zep = zip_error_code_zip(err);
449-
zip_error_fini(err);
449+
err = zip_get_error(obj->za);
450+
zep = zip_error_code_zip(err);
451+
zip_error_fini(err);
450452
#endif
453+
}
451454
return zep;
452455
}
453456
/* }}} */
@@ -460,26 +463,32 @@ static zend_long php_zip_last_id(ze_zip_object *obj) /* {{{ */
460463

461464
static zend_long php_zip_status_sys(ze_zip_object *obj) /* {{{ */
462465
{
466+
int syp = obj->err_sys; /* saved err if closed */
467+
468+
if (obj->za) {
463469
#if LIBZIP_VERSION_MAJOR < 1
464-
int zep, syp;
470+
int zep;
465471

466-
zip_error_get(obj->za, &zep, &syp);
472+
zip_error_get(obj->za, &zep, &syp);
467473
#else
468-
int syp;
469-
zip_error_t *err;
474+
zip_error_t *err;
470475

471-
err = zip_get_error(obj->za);
472-
syp = zip_error_code_system(err);
473-
zip_error_fini(err);
476+
err = zip_get_error(obj->za);
477+
syp = zip_error_code_system(err);
478+
zip_error_fini(err);
474479
#endif
480+
}
475481
return syp;
476482
}
477483
/* }}} */
478484

479485
static zend_long php_zip_get_num_files(ze_zip_object *obj) /* {{{ */
480486
{
481-
zip_int64_t num = zip_get_num_entries(obj->za, 0);
482-
return MIN(num, ZEND_LONG_MAX);
487+
if (obj->za) {
488+
zip_int64_t num = zip_get_num_entries(obj->za, 0);
489+
return MIN(num, ZEND_LONG_MAX);
490+
}
491+
return 0;
483492
}
484493
/* }}} */
485494

@@ -803,12 +812,10 @@ static zval *php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd,
803812
zend_long retint = 0;
804813
int len = 0;
805814

806-
if (obj && obj->za != NULL) {
807-
if (hnd->read_const_char_func) {
808-
retchar = hnd->read_const_char_func(obj, &len);
809-
} else if (hnd->read_int_func) {
810-
retint = hnd->read_int_func(obj);
811-
}
815+
if (hnd->read_const_char_func) {
816+
retchar = hnd->read_const_char_func(obj, &len);
817+
} else if (hnd->read_int_func) {
818+
retint = hnd->read_int_func(obj);
812819
}
813820

814821
switch (hnd->type) {
@@ -1488,7 +1495,23 @@ static ZIPARCHIVE_METHOD(close)
14881495

14891496
ze_obj = Z_ZIP_P(self);
14901497

1491-
if ((err = zip_close(intern))) {
1498+
err = zip_close(intern);
1499+
1500+
/* Save error for property reader */
1501+
#if LIBZIP_VERSION_MAJOR < 1
1502+
zip_error_get(obj->za, &ze_obj->err_zip, &ze_obj->err_sys);
1503+
#else
1504+
{
1505+
zip_error_t *ziperr;
1506+
1507+
ziperr = zip_get_error(intern);
1508+
ze_obj->err_zip = zip_error_code_zip(ziperr);
1509+
ze_obj->err_sys = zip_error_code_system(ziperr);
1510+
zip_error_fini(ziperr);
1511+
}
1512+
#endif
1513+
1514+
if (err) {
14921515
#if LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR == 3 && LIBZIP_VERSION_MICRO == 1
14931516
php_error_docref(NULL, E_WARNING, "zip_close have failed");
14941517
#else
@@ -1533,30 +1556,42 @@ static ZIPARCHIVE_METHOD(count)
15331556
* Returns the status error message, system and/or zip messages */
15341557
static ZIPARCHIVE_METHOD(getStatusString)
15351558
{
1536-
struct zip *intern;
15371559
zval *self = ZEND_THIS;
15381560
#if LIBZIP_VERSION_MAJOR < 1
15391561
int zep, syp, len;
15401562
char error_string[128];
1541-
#else
1542-
zip_error_t *err;
15431563
#endif
1564+
ze_zip_object *ze_obj;
15441565

15451566
if (zend_parse_parameters_none() == FAILURE) {
15461567
RETURN_THROWS();
15471568
}
15481569

1549-
ZIP_FROM_OBJECT(intern, self);
1570+
ze_obj = Z_ZIP_P(self); /* not ZIP_FROM_OBJECT as we can use saved error after close */
15501571

15511572
#if LIBZIP_VERSION_MAJOR < 1
1552-
zip_error_get(intern, &zep, &syp);
1553-
1554-
len = zip_error_to_str(error_string, 128, zep, syp);
1573+
if (ze_obj->za) {
1574+
zip_error_get(ze_obj->za, &zep, &syp);
1575+
len = zip_error_to_str(error_string, 128, zep, syp);
1576+
} else {
1577+
len = zip_error_to_str(error_string, 128, ze_obj->err_zip, ze_obj->err_sys);
1578+
}
15551579
RETVAL_STRINGL(error_string, len);
15561580
#else
1557-
err = zip_get_error(intern);
1558-
RETVAL_STRING(zip_error_strerror(err));
1559-
zip_error_fini(err);
1581+
if (ze_obj->za) {
1582+
zip_error_t *err;
1583+
1584+
err = zip_get_error(ze_obj->za);
1585+
RETVAL_STRING(zip_error_strerror(err));
1586+
zip_error_fini(err);
1587+
} else {
1588+
zip_error_t err;
1589+
1590+
zip_error_init_with_code(&err, ze_obj->err_zip);
1591+
err.sys_err = ze_obj->err_sys; /* missing setter */
1592+
RETVAL_STRING(zip_error_strerror(&err));
1593+
zip_error_fini(&err);
1594+
}
15601595
#endif
15611596
}
15621597
/* }}} */
@@ -3159,7 +3194,7 @@ static PHP_MINIT_FUNCTION(zip)
31593194
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OS_2", ZIP_OPSYS_OS_2);
31603195
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MACINTOSH", ZIP_OPSYS_MACINTOSH);
31613196
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_SYSTEM", ZIP_OPSYS_Z_SYSTEM);
3162-
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_CPM", ZIP_OPSYS_CPM); // typo kept for BC
3197+
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_CPM", ZIP_OPSYS_CPM); /* typo kept for BC */
31633198
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_CPM", ZIP_OPSYS_CPM);
31643199
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_WINDOWS_NTFS", ZIP_OPSYS_WINDOWS_NTFS);
31653200
REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MVS", ZIP_OPSYS_MVS);

ext/zip/php_zip.h

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ typedef struct _ze_zip_object {
6060
int filename_len;
6161
int buffers_cnt;
6262
zip_int64_t last_id;
63+
int err_zip;
64+
int err_sys;
6365
#ifdef HAVE_PROGRESS_CALLBACK
6466
zval progress_callback;
6567
#endif

ext/zip/tests/bug38943.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ object(myZip)#1 (%d) {
3838
int(1)
3939
}
4040
["lastId"]=>
41-
int(0)
41+
int(-1)
4242
["status"]=>
4343
int(0)
4444
["statusSys"]=>

ext/zip/tests/bug38943_2.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ object(myZip)#1 (%d) {
2424
int(1)
2525
}
2626
["lastId"]=>
27-
int(0)
27+
int(-1)
2828
["status"]=>
2929
int(0)
3030
["statusSys"]=>

ext/zip/tests/oo_cancel.phpt

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ var_dump($zip->registerCancelCallback(function () {
2727
var_dump($zip->addFromString(PHP_BINARY, 'entry #1'));
2828

2929
var_dump($zip->close());
30+
var_dump($zip->status == ZipArchive::ER_CANCELLED);
31+
var_dump($zip->getStatusString());
3032
@unlink($file);
3133
?>
3234
Done
@@ -36,4 +38,6 @@ bool(true)
3638

3739
Warning: ZipArchive::close(): Operation cancelled in %s
3840
bool(false)
41+
bool(true)
42+
string(19) "Operation cancelled"
3943
Done

0 commit comments

Comments
 (0)