]> granicus.if.org Git - php/commitdiff
- make status, statusSys properties and
authorRemi Collet <remi@php.net>
Thu, 5 Mar 2020 09:57:26 +0000 (10:57 +0100)
committerRemi Collet <remi@php.net>
Thu, 5 Mar 2020 09:57:26 +0000 (10:57 +0100)
  ZipArchive::getStatusString() method   available after archive is closed

NEWS
ext/zip/php_zip.c
ext/zip/php_zip.h
ext/zip/tests/bug38943.phpt
ext/zip/tests/bug38943_2.phpt
ext/zip/tests/oo_cancel.phpt

diff --git a/NEWS b/NEWS
index b8496a37313ead1c21c7197b55a3f1d621bd8342..fa0a8cdc905fa68375acfe94d82ad78c0bd2c3a6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -139,7 +139,10 @@ PHP                                                                        NEWS
     addFromString methods. (Remi)
   . Add "flags" options to ZipArchive::addGlob and addPattern methods
     keeping previous behavior having FL_OVERWRITE by default. (Remi)
-  . Add ZipArchive::replaceFile() method
-  . Add lastId property to ZipArchive
+  . Add ZipArchive::replaceFile() method. (Remi)
+  . Add lastId property to ZipArchive. (Remi)
+  . ZipArchive::status and ZipArchive::statusSys properties and
+    ZipArchive::getStatusString() method stay valid after the archive
+    is closed. (Remi)
 
 <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
index ed562eae6d7968e05f371c4e3d3168ee809a3c8f..34ef7ccde624849aac56fdb11da4d97e566e425f 100644 (file)
@@ -304,7 +304,7 @@ static int php_zip_add_file(ze_zip_object *obj, const char *filename, size_t fil
        if (!zs) {
                return -1;
        }
-       // Replace
+       /* Replace */
        if (replace >= 0) {
                if (zip_file_replace(obj->za, replace, zs, flags) < 0) {
                        zip_source_free(zs);
@@ -313,7 +313,7 @@ static int php_zip_add_file(ze_zip_object *obj, const char *filename, size_t fil
                zip_error_clear(obj->za);
                return 1;
        }
-       // Add
+       /* Add */
        obj->last_id = zip_file_add(obj->za, entry_name, zs, flags);
        if (obj->last_id < 0) {
                zip_source_free(zs);
@@ -436,18 +436,21 @@ static int php_zip_parse_options(zval *options, zend_long *remove_all_path,
 
 static zend_long php_zip_status(ze_zip_object *obj) /* {{{ */
 {
+       int zep = obj->err_zip; /* saved err if closed */
+
+       if (obj->za) {
 #if LIBZIP_VERSION_MAJOR < 1
-       int zep, syp;
+               int syp;
 
-       zip_error_get(obj->za, &zep, &syp);
+               zip_error_get(obj->za, &zep, &syp);
 #else
-       int zep;
-       zip_error_t *err;
+               zip_error_t *err;
 
-       err = zip_get_error(obj->za);
-       zep = zip_error_code_zip(err);
-       zip_error_fini(err);
+               err = zip_get_error(obj->za);
+               zep = zip_error_code_zip(err);
+               zip_error_fini(err);
 #endif
+       }
        return zep;
 }
 /* }}} */
@@ -460,26 +463,32 @@ static zend_long php_zip_last_id(ze_zip_object *obj) /* {{{ */
 
 static zend_long php_zip_status_sys(ze_zip_object *obj) /* {{{ */
 {
+       int syp = obj->err_sys;  /* saved err if closed */
+
+       if (obj->za) {
 #if LIBZIP_VERSION_MAJOR < 1
-       int zep, syp;
+               int zep;
 
-       zip_error_get(obj->za, &zep, &syp);
+               zip_error_get(obj->za, &zep, &syp);
 #else
-       int syp;
-       zip_error_t *err;
+               zip_error_t *err;
 
-       err = zip_get_error(obj->za);
-       syp = zip_error_code_system(err);
-       zip_error_fini(err);
+               err = zip_get_error(obj->za);
+               syp = zip_error_code_system(err);
+               zip_error_fini(err);
 #endif
+       }
        return syp;
 }
 /* }}} */
 
 static zend_long php_zip_get_num_files(ze_zip_object *obj) /* {{{ */
 {
-       zip_int64_t num = zip_get_num_entries(obj->za, 0);
-       return MIN(num, ZEND_LONG_MAX);
+       if (obj->za) {
+               zip_int64_t num = zip_get_num_entries(obj->za, 0);
+               return MIN(num, ZEND_LONG_MAX);
+       }
+       return 0;
 }
 /* }}} */
 
@@ -803,12 +812,10 @@ static zval *php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd,
        zend_long retint = 0;
        int len = 0;
 
-       if (obj && obj->za != NULL) {
-               if (hnd->read_const_char_func) {
-                       retchar = hnd->read_const_char_func(obj, &len);
-               } else if (hnd->read_int_func) {
-                       retint = hnd->read_int_func(obj);
-               }
+       if (hnd->read_const_char_func) {
+               retchar = hnd->read_const_char_func(obj, &len);
+       } else if (hnd->read_int_func) {
+               retint = hnd->read_int_func(obj);
        }
 
        switch (hnd->type) {
@@ -1488,7 +1495,23 @@ static ZIPARCHIVE_METHOD(close)
 
        ze_obj = Z_ZIP_P(self);
 
-       if ((err = zip_close(intern))) {
+       err = zip_close(intern);
+
+       /* Save error for property reader */
+#if LIBZIP_VERSION_MAJOR < 1
+       zip_error_get(obj->za, &ze_obj->err_zip, &ze_obj->err_sys);
+#else
+       {
+       zip_error_t *ziperr;
+
+       ziperr = zip_get_error(intern);
+       ze_obj->err_zip = zip_error_code_zip(ziperr);
+       ze_obj->err_sys = zip_error_code_system(ziperr);
+       zip_error_fini(ziperr);
+       }
+#endif
+
+       if (err) {
 #if LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR == 3 && LIBZIP_VERSION_MICRO == 1
                php_error_docref(NULL, E_WARNING, "zip_close have failed");
 #else
@@ -1533,30 +1556,42 @@ static ZIPARCHIVE_METHOD(count)
  * Returns the status error message, system and/or zip messages */
 static ZIPARCHIVE_METHOD(getStatusString)
 {
-       struct zip *intern;
        zval *self = ZEND_THIS;
 #if LIBZIP_VERSION_MAJOR < 1
        int zep, syp, len;
        char error_string[128];
-#else
-       zip_error_t *err;
 #endif
+       ze_zip_object *ze_obj;
 
        if (zend_parse_parameters_none() == FAILURE) {
                RETURN_THROWS();
        }
 
-       ZIP_FROM_OBJECT(intern, self);
+       ze_obj = Z_ZIP_P(self); /* not ZIP_FROM_OBJECT as we can use saved error after close */
 
 #if LIBZIP_VERSION_MAJOR < 1
-       zip_error_get(intern, &zep, &syp);
-
-       len = zip_error_to_str(error_string, 128, zep, syp);
+       if (ze_obj->za) {
+               zip_error_get(ze_obj->za, &zep, &syp);
+               len = zip_error_to_str(error_string, 128, zep, syp);
+       } else {
+               len = zip_error_to_str(error_string, 128, ze_obj->err_zip, ze_obj->err_sys);
+       }
        RETVAL_STRINGL(error_string, len);
 #else
-       err = zip_get_error(intern);
-       RETVAL_STRING(zip_error_strerror(err));
-       zip_error_fini(err);
+       if (ze_obj->za) {
+               zip_error_t *err;
+
+               err = zip_get_error(ze_obj->za);
+               RETVAL_STRING(zip_error_strerror(err));
+               zip_error_fini(err);
+       } else {
+               zip_error_t err;
+
+               zip_error_init_with_code(&err, ze_obj->err_zip);
+               err.sys_err = ze_obj->err_sys; /* missing setter */
+               RETVAL_STRING(zip_error_strerror(&err));
+               zip_error_fini(&err);
+       }
 #endif
 }
 /* }}} */
@@ -3159,7 +3194,7 @@ static PHP_MINIT_FUNCTION(zip)
        REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OS_2",                             ZIP_OPSYS_OS_2);
        REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MACINTOSH",                ZIP_OPSYS_MACINTOSH);
        REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_SYSTEM",                 ZIP_OPSYS_Z_SYSTEM);
-       REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_CPM",                    ZIP_OPSYS_CPM);  // typo kept for BC
+       REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_CPM",                    ZIP_OPSYS_CPM);  /* typo kept for BC */
        REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_CPM",                              ZIP_OPSYS_CPM);
        REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_WINDOWS_NTFS",             ZIP_OPSYS_WINDOWS_NTFS);
        REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MVS",                              ZIP_OPSYS_MVS);
index f28937ebe266f9b7ea53aaeeab3783183cafdb39..1f3ec76f02f399ee94a30f3c962ee890bb2c7455 100644 (file)
@@ -60,6 +60,8 @@ typedef struct _ze_zip_object {
        int filename_len;
        int buffers_cnt;
        zip_int64_t last_id;
+       int err_zip;
+       int err_sys;
 #ifdef HAVE_PROGRESS_CALLBACK
        zval progress_callback;
 #endif
index e2819d0948a15735f224b2147ed21570104e8035..f079f81153e78212fcd83cfee00b854dad2613c3 100644 (file)
@@ -38,7 +38,7 @@ object(myZip)#1 (%d) {
     int(1)
   }
   ["lastId"]=>
-  int(0)
+  int(-1)
   ["status"]=>
   int(0)
   ["statusSys"]=>
index 0b6612f254fdcec187b9f8b2427c3b4e368e7a25..fa2a086b1975d942e8d346d4b61ceffc9e9ced05 100644 (file)
@@ -24,7 +24,7 @@ object(myZip)#1 (%d) {
     int(1)
   }
   ["lastId"]=>
-  int(0)
+  int(-1)
   ["status"]=>
   int(0)
   ["statusSys"]=>
index 4c487072c0383c9a0ea3869c18726c7a42f3507a..2da21d99046380b8e769fa7605a70760094a3ed2 100644 (file)
@@ -27,6 +27,8 @@ var_dump($zip->registerCancelCallback(function () {
 var_dump($zip->addFromString(PHP_BINARY, 'entry #1'));
 
 var_dump($zip->close());
+var_dump($zip->status == ZipArchive::ER_CANCELLED);
+var_dump($zip->getStatusString());
 @unlink($file);
 ?>
 Done
@@ -36,4 +38,6 @@ bool(true)
 
 Warning: ZipArchive::close(): Operation cancelled in %s
 bool(false)
+bool(true)
+string(19) "Operation cancelled"
 Done