@@ -576,7 +576,7 @@ static char * php_zipobj_get_zip_comment(ze_zip_object *obj, int *len) /* {{{ */
576576/* }}} */
577577
578578/* Close and free the zip_t */
579- static bool php_zipobj_close (ze_zip_object * obj ) /* {{{ */
579+ static bool php_zipobj_close (ze_zip_object * obj , zend_string * * out_str ) /* {{{ */
580580{
581581 struct zip * intern = obj -> za ;
582582 bool success = false;
@@ -608,7 +608,17 @@ static bool php_zipobj_close(ze_zip_object *obj) /* {{{ */
608608 obj -> filename_len = 0 ;
609609 }
610610
611+ if (obj -> out_str ) {
612+ if (out_str ) {
613+ * out_str = obj -> out_str ;
614+ } else {
615+ zend_string_release (obj -> out_str );
616+ }
617+ obj -> out_str = NULL ;
618+ }
619+
611620 obj -> za = NULL ;
621+ obj -> from_string = false;
612622 return success ;
613623}
614624/* }}} */
@@ -1060,7 +1070,7 @@ static void php_zip_object_free_storage(zend_object *object) /* {{{ */
10601070{
10611071 ze_zip_object * intern = php_zip_fetch_object (object );
10621072
1063- php_zipobj_close (intern );
1073+ php_zipobj_close (intern , NULL );
10641074
10651075#ifdef HAVE_PROGRESS_CALLBACK
10661076 /* if not properly called by libzip */
@@ -1467,7 +1477,7 @@ PHP_METHOD(ZipArchive, open)
14671477 }
14681478
14691479 /* If we already have an opened zip, free it */
1470- php_zipobj_close (ze_obj );
1480+ php_zipobj_close (ze_obj , NULL );
14711481
14721482 /* open for write without option to empty the archive */
14731483 if ((flags & (ZIP_TRUNCATE | ZIP_RDONLY )) == 0 ) {
@@ -1491,28 +1501,34 @@ PHP_METHOD(ZipArchive, open)
14911501 ze_obj -> filename = resolved_path ;
14921502 ze_obj -> filename_len = strlen (resolved_path );
14931503 ze_obj -> za = intern ;
1504+ ze_obj -> from_string = false;
14941505 RETURN_TRUE ;
14951506}
14961507/* }}} */
14971508
14981509/* {{{ Create new read-only zip using given string */
14991510PHP_METHOD (ZipArchive , openString )
15001511{
1501- zend_string * buffer ;
1512+ zend_string * buffer = NULL ;
1513+ zend_long flags = 0 ;
15021514 zval * self = ZEND_THIS ;
15031515
1504- if (zend_parse_parameters (ZEND_NUM_ARGS (), "S " , & buffer ) == FAILURE ) {
1516+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "|Sl " , & buffer , & flags ) == FAILURE ) {
15051517 RETURN_THROWS ();
15061518 }
15071519
1520+ if (!buffer ) {
1521+ buffer = ZSTR_EMPTY_ALLOC ();
1522+ }
1523+
15081524 ze_zip_object * ze_obj = Z_ZIP_P (self );
15091525
1510- php_zipobj_close (ze_obj );
1526+ php_zipobj_close (ze_obj , NULL );
15111527
15121528 zip_error_t err ;
15131529 zip_error_init (& err );
15141530
1515- zip_source_t * zip_source = php_zip_create_string_source (buffer , NULL , & err );
1531+ zip_source_t * zip_source = php_zip_create_string_source (buffer , & ze_obj -> out_str , & err );
15161532
15171533 if (!zip_source ) {
15181534 ze_obj -> err_zip = zip_error_code_zip (& err );
@@ -1521,7 +1537,7 @@ PHP_METHOD(ZipArchive, openString)
15211537 RETURN_LONG (ze_obj -> err_zip );
15221538 }
15231539
1524- struct zip * intern = zip_open_from_source (zip_source , ZIP_RDONLY , & err );
1540+ struct zip * intern = zip_open_from_source (zip_source , flags , & err );
15251541 if (!intern ) {
15261542 ze_obj -> err_zip = zip_error_code_zip (& err );
15271543 ze_obj -> err_sys = zip_error_code_system (& err );
@@ -1530,6 +1546,7 @@ PHP_METHOD(ZipArchive, openString)
15301546 RETURN_LONG (ze_obj -> err_zip );
15311547 }
15321548
1549+ ze_obj -> from_string = true;
15331550 ze_obj -> za = intern ;
15341551 zip_error_fini (& err );
15351552 RETURN_TRUE ;
@@ -1568,7 +1585,32 @@ PHP_METHOD(ZipArchive, close)
15681585
15691586 ZIP_FROM_OBJECT (intern , self );
15701587
1571- RETURN_BOOL (php_zipobj_close (Z_ZIP_P (self )));
1588+ RETURN_BOOL (php_zipobj_close (Z_ZIP_P (self ), NULL ));
1589+ }
1590+ /* }}} */
1591+
1592+ /* {{{ close the zip archive and get the result as a string */
1593+ PHP_METHOD (ZipArchive , closeString )
1594+ {
1595+ struct zip * intern ;
1596+ zval * self = ZEND_THIS ;
1597+
1598+ ZEND_PARSE_PARAMETERS_NONE ();
1599+
1600+ ZIP_FROM_OBJECT (intern , self );
1601+
1602+ if (!Z_ZIP_P (self )-> from_string ) {
1603+ zend_throw_error (NULL , "ZipArchive::closeString can only be called on "
1604+ "an archive opened with ZipArchive::openString" );
1605+ RETURN_THROWS ();
1606+ }
1607+
1608+ zend_string * ret = NULL ;
1609+ bool success = php_zipobj_close (Z_ZIP_P (self ), & ret );
1610+ if (success ) {
1611+ RETURN_STR (ret ? ret : ZSTR_EMPTY_ALLOC ());
1612+ }
1613+ RETURN_FALSE ;
15721614}
15731615/* }}} */
15741616
0 commit comments