php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #62106
Patch 62106.patch revision 2020-03-19 17:43 UTC by tatzaad at gmail dot com
revision 2012-07-10 14:14 UTC by ab@php.net

Patch 62106.patch for Zip Related Bug #62106

Patch version 2020-03-19 17:43 UTC

Return to Bug #62106 | Download this patch
This patch renders other patches obsolete

Obsolete patches:

Patch Revisions:

Developer: tatzaad@gmail.com

diff --git a/ext/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c
index 362f92d..c57cf3f 100644
--- a/ext/zip/lib/zip_close.c
+++ b/ext/zip/lib/zip_close.c
@@ -49,6 +49,11 @@
 #include <fcntl.h>
 #endif
 
+#include "php.h"
+#include "php_zip.h"
+
+ZEND_DECLARE_MODULE_GLOBALS(zip)
+
 static int add_data(struct zip *, struct zip_source *, struct zip_dirent *,
 		    FILE *);
 static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
@@ -83,6 +88,8 @@ zip_close(struct zip *za)
     int reopen_on_error;
     int new_torrentzip;
 
+	TSRMLS_FETCH();
+
     reopen_on_error = 0;
 
     if (za == NULL)
@@ -142,6 +149,7 @@ zip_close(struct zip *za)
 	free(filelist);
 	return -1;
     }
+	PHP_ZIP_FNAME_REC(temp)
 
 
     /* create list of files with index into original archive  */
@@ -306,14 +314,14 @@ zip_close(struct zip *za)
 	_zip_dirent_finalize(&de);
 	fclose(out);
 	remove(temp);
-	free(temp);
+	PHP_ZIP_FNAME_FREE(temp)
 	return -1;
     }
 
     if (fclose(out) != 0) {
 	_zip_error_set(&za->error, ZIP_ER_CLOSE, errno);
 	remove(temp);
-	free(temp);
+	PHP_ZIP_FNAME_FREE(temp)
 	return -1;
     }
     
@@ -325,7 +333,7 @@ zip_close(struct zip *za)
     if (_zip_rename(temp, za->zn) != 0) {
 	_zip_error_set(&za->error, ZIP_ER_RENAME, errno);
 	remove(temp);
-	free(temp);
+	PHP_ZIP_FNAME_FREE(temp)
 	if (reopen_on_error) {
 	    /* ignore errors, since we're already in an error case */
 	    za->zp = fopen(za->zn, "rb");
@@ -339,7 +347,7 @@ zip_close(struct zip *za)
 #endif
 
     _zip_free(za);
-	free(temp);
+	PHP_ZIP_FNAME_FREE(temp)
 
     return 0;
 }
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index 74f868b..d3d0a6b 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -52,6 +52,8 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_close);
 #endif
 #endif
 
+ZEND_DECLARE_MODULE_GLOBALS(zip)
+
 /* {{{ Resource le */
 static int le_zip_dir;
 #define le_zip_dir_name "Zip Directory"
@@ -1175,6 +1177,8 @@ static void php_zip_free_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 static PHP_MINIT_FUNCTION(zip);
 static PHP_MSHUTDOWN_FUNCTION(zip);
 static PHP_MINFO_FUNCTION(zip);
+static PHP_RINIT_FUNCTION(zip);
+static PHP_RSHUTDOWN_FUNCTION(zip);
 /* }}} */
 
 /* {{{ zip_module_entry
@@ -1185,8 +1189,8 @@ zend_module_entry zip_module_entry = {
 	zip_functions,
 	PHP_MINIT(zip),
 	PHP_MSHUTDOWN(zip),
-	NULL,
-	NULL,
+	PHP_RINIT(zip),
+	PHP_RSHUTDOWN(zip),
 	PHP_MINFO(zip),
 	PHP_ZIP_VERSION_STRING,
 	STANDARD_MODULE_PROPERTIES
@@ -2759,12 +2763,23 @@ static const zend_function_entry zip_class_functions[] = {
 /* }}} */
 #endif
 
+/* {{{ php_zip_init_globals */
+static void php_zip_init_globals(zend_zip_globals *zip_globals TSRMLS_DC)
+{
+	zip_globals->fname_head = NULL;
+	zip_globals->fname_tail = NULL;
+	zip_globals->fname_lock = 0;
+}
+/* }}} */
+
 /* {{{ PHP_MINIT_FUNCTION */
 static PHP_MINIT_FUNCTION(zip)
 {
 #ifdef PHP_ZIP_USE_OO 
 	zend_class_entry ce;
 
+	ZEND_INIT_MODULE_GLOBALS(zip, php_zip_init_globals, NULL);
+
 	memcpy(&zip_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
 	zip_object_handlers.clone_obj		= NULL;
 	zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr;
@@ -2874,6 +2889,45 @@ static PHP_MINFO_FUNCTION(zip)
 }
 /* }}} */
 
+/* {{{ PHP_RINIT_FUNCTION */
+static PHP_RINIT_FUNCTION(zip)
+{
+	ZIPG(fname_head) = NULL;
+	ZIPG(fname_tail) = NULL;
+	ZIPG(fname_lock) = 0;
+
+	return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_RSHUTDOWN_FUNCTION */
+static PHP_RSHUTDOWN_FUNCTION(zip)
+{
+	struct zip_fnode *hd = ZIPG(fname_head), *nxt;
+
+	/* lock and clean up, even something'd want to cleanup 
+	   after this, the list would be empty */
+	while(ZIPG(fname_lock));
+	PHP_ZIP_FNAME_LOCK
+
+	while(hd) {
+		nxt = hd->next;
+
+		remove(hd->val);
+		free(hd->val);
+		efree(hd);
+
+		hd = nxt;
+	}
+
+	ZIPG(fname_head) = NULL;
+	ZIPG(fname_tail) = NULL;
+	PHP_ZIP_FNAME_UNLOCK
+
+	return SUCCESS;
+}
+/* }}} */
+
 /*
  * Local variables:
  * tab-width: 4
diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h
index f848ade..a29198e 100644
--- a/ext/zip/php_zip.h
+++ b/ext/zip/php_zip.h
@@ -87,6 +87,72 @@ php_stream *php_stream_zip_open(char *filename, char *path, char *mode STREAMS_D
 extern php_stream_wrapper php_stream_zip_wrapper;
 #endif
 
+struct zip_fnode {
+	char *val;
+	struct zip_fnode *next;
+	struct zip_fnode *prev;
+};
+
+ZEND_BEGIN_MODULE_GLOBALS(zip)
+	struct zip_fnode *fname_head;
+	struct zip_fnode *fname_tail;
+	int fname_lock;
+ZEND_END_MODULE_GLOBALS(zip)
+
+#ifdef ZTS
+# define ZIPG(v) TSRMG(zip_globals_id, zend_zip_globals *, v)
+#else
+# define ZIPG(v) (zip_globals.v)
+#endif
+
+#define PHP_ZIP_FNAME_LOCK ZIPG(fname_lock) = 1;
+#define PHP_ZIP_FNAME_UNLOCK ZIPG(fname_lock) = 0;
+
+#define PHP_ZIP_FNAME_REC(fname) \
+	while(ZIPG(fname_lock)); \
+	PHP_ZIP_FNAME_LOCK \
+	do { \
+		struct zip_fnode *nxt = (struct zip_fnode *) emalloc(sizeof(struct zip_fnode)); \
+		nxt->val = fname; \
+		if (NULL == ZIPG(fname_head)) { \
+			ZIPG(fname_head) = nxt; \
+			nxt->prev = NULL; \
+		} else { \
+			ZIPG(fname_tail)->next = nxt; \
+			nxt->prev = ZIPG(fname_tail); \
+		} \
+		ZIPG(fname_tail) = nxt; \
+		nxt->next = NULL; \
+	} while (0); \
+	PHP_ZIP_FNAME_UNLOCK
+
+#define PHP_ZIP_FNAME_FREE(fname) \
+	while(ZIPG(fname_lock)); \
+	PHP_ZIP_FNAME_LOCK \
+	do { \
+		struct zip_fnode *hd = ZIPG(fname_head); \
+		while(hd) { \
+			if (hd->val == fname) { \
+				if (NULL == hd->prev) { \
+					ZIPG(fname_head) = hd->next; \
+				} else { \
+					hd->prev->next = hd->next; \
+				} \
+				if (NULL == hd->next) { \
+					ZIPG(fname_tail) = hd->prev; \
+				} else { \
+					hd->next->prev = hd->prev; \
+				} \
+				free(fname); \
+				efree(hd); \
+				break; \
+			} \
+			hd = hd->next; \
+		} \
+	} while(0); \
+	PHP_ZIP_FNAME_UNLOCK
+	
+
 #endif	/* PHP_ZIP_H */
 
 /*
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 17:01:32 2024 UTC