Skip to content

Commit 8e22d7c

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fix TsHashTable related race conditions
2 parents 4f5c6bc + 98b6330 commit 8e22d7c

File tree

4 files changed

+66
-16
lines changed

4 files changed

+66
-16
lines changed

ext/com_dotnet/com_com.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ PHP_FUNCTION(com_create_instance)
267267
if (SUCCEEDED(ITypeLib_GetDocumentation(TL, -1, &name, NULL, NULL, NULL))) {
268268
typelib_name = php_com_olestring_to_string(name, &typelib_name_len, obj->code_page);
269269

270-
if (NULL != zend_ts_hash_str_add_ptr(&php_com_typelibraries, typelib_name, typelib_name_len, TL)) {
270+
if (NULL != php_com_cache_typelib(TL, typelib_name, typelib_name_len)) {
271271
php_com_import_typelib(TL, mode, obj->code_page);
272272

273273
/* add a reference for the hash */

ext/com_dotnet/com_extension.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
ZEND_DECLARE_MODULE_GLOBALS(com_dotnet)
3434
static PHP_GINIT_FUNCTION(com_dotnet);
3535

36-
TsHashTable php_com_typelibraries;
37-
3836
zend_class_entry
3937
*php_com_variant_class_entry,
4038
*php_com_exception_class_entry,
@@ -330,8 +328,6 @@ PHP_MINIT_FUNCTION(com_dotnet)
330328
tmp->serialize = zend_class_serialize_deny;
331329
tmp->unserialize = zend_class_unserialize_deny;
332330

333-
zend_ts_hash_init(&php_com_typelibraries, 0, NULL, php_com_typelibrary_dtor, 1);
334-
335331
#if HAVE_MSCOREE_H
336332
INIT_CLASS_ENTRY(ce, "dotnet", NULL);
337333
ce.create_object = php_com_object_new;
@@ -418,6 +414,9 @@ PHP_MINIT_FUNCTION(com_dotnet)
418414
COM_CONST(VT_UI8);
419415
COM_CONST(VT_I8);
420416
#endif
417+
418+
PHP_MINIT(com_typeinfo)(INIT_FUNC_ARGS_PASSTHRU);
419+
421420
return SUCCESS;
422421
}
423422
/* }}} */
@@ -433,7 +432,8 @@ PHP_MSHUTDOWN_FUNCTION(com_dotnet)
433432
}
434433
#endif
435434

436-
zend_ts_hash_destroy(&php_com_typelibraries);
435+
PHP_MSHUTDOWN(com_typeinfo)(INIT_FUNC_ARGS_PASSTHRU);
436+
437437
return SUCCESS;
438438
}
439439
/* }}} */

ext/com_dotnet/com_typeinfo.c

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,33 @@
2727
#include "php_com_dotnet.h"
2828
#include "php_com_dotnet_internal.h"
2929

30+
static HashTable php_com_typelibraries;
31+
32+
#ifdef ZTS
33+
static MUTEX_T php_com_typelibraries_mutex;
34+
#endif
35+
36+
PHP_MINIT_FUNCTION(com_typeinfo)
37+
{
38+
zend_hash_init(&php_com_typelibraries, 0, NULL, php_com_typelibrary_dtor, 1);
39+
40+
#ifdef ZTS
41+
php_com_typelibraries_mutex = tsrm_mutex_alloc();
42+
#endif
43+
44+
return SUCCESS;
45+
}
46+
47+
PHP_MSHUTDOWN_FUNCTION(com_typeinfo)
48+
{
49+
zend_hash_destroy(&php_com_typelibraries);
50+
51+
#ifdef ZTS
52+
tsrm_mutex_free(php_com_typelibraries_mutex);
53+
#endif
54+
55+
return SUCCESS;
56+
}
3057

3158
/* The search string can be either:
3259
* a) a file name
@@ -220,35 +247,58 @@ void php_com_typelibrary_dtor(zval *pDest)
220247
ITypeLib_Release(Lib);
221248
}
222249

250+
ITypeLib *php_com_cache_typelib(ITypeLib* TL, char *cache_key, zend_long cache_key_len) {
251+
ITypeLib* result;
252+
#ifdef ZTS
253+
tsrm_mutex_lock(php_com_typelibraries_mutex);
254+
#endif
255+
256+
result = zend_hash_str_add_ptr(&php_com_typelibraries, cache_key, cache_key_len, TL);
257+
258+
#ifdef ZTS
259+
tsrm_mutex_unlock(php_com_typelibraries_mutex);
260+
#endif
261+
262+
return result;
263+
}
264+
223265
PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib_via_cache(char *search_string,
224266
int codepage, int *cached)
225267
{
226268
ITypeLib *TL;
227269
char *name_dup;
228-
size_t l;
270+
zend_string *key = zend_string_init(search_string, strlen(search_string), 1);
229271

230-
l = strlen(search_string);
272+
#ifdef ZTS
273+
tsrm_mutex_lock(php_com_typelibraries_mutex);
274+
#endif
231275

232-
if ((TL = zend_ts_hash_str_find_ptr(&php_com_typelibraries, search_string, l)) != NULL) {
276+
if ((TL = zend_hash_find_ptr(&php_com_typelibraries, key)) != NULL) {
233277
*cached = 1;
234278
/* add a reference for the caller */
235279
ITypeLib_AddRef(TL);
236-
return TL;
280+
281+
goto php_com_load_typelib_via_cache_return;
237282
}
238283

239284
*cached = 0;
240-
name_dup = estrndup(search_string, l);
285+
name_dup = estrndup(ZSTR_VAL(key), ZSTR_LEN(key));
241286
TL = php_com_load_typelib(name_dup, codepage);
242287
efree(name_dup);
243288

244289
if (TL) {
245-
if (NULL != zend_ts_hash_str_update_ptr(&php_com_typelibraries,
246-
search_string, l, TL)) {
290+
if (NULL != zend_hash_add_ptr(&php_com_typelibraries, key, TL)) {
247291
/* add a reference for the hash table */
248292
ITypeLib_AddRef(TL);
249293
}
250294
}
251295

296+
php_com_load_typelib_via_cache_return:
297+
#ifdef ZTS
298+
tsrm_mutex_unlock(php_com_typelibraries_mutex);
299+
#endif
300+
zend_string_release(key);
301+
252302
return TL;
253303
}
254304

ext/com_dotnet/php_com_dotnet_internal.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
#include <dispex.h>
2828
#include "win32/winutil.h"
2929

30-
#include "zend_ts_hash.h"
31-
3230
typedef struct _php_com_dotnet_object {
3331
zend_object zo;
3432

@@ -70,7 +68,6 @@ static inline int php_com_is_valid_object(zval *zv)
7068
} while(0)
7169

7270
/* com_extension.c */
73-
TsHashTable php_com_typelibraries;
7471
zend_class_entry *php_com_variant_class_entry, *php_com_exception_class_entry, *php_com_saproxy_class_entry;
7572

7673
/* com_handlers.c */
@@ -175,6 +172,9 @@ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode,
175172
void php_com_typelibrary_dtor(zval *pDest);
176173
ITypeInfo *php_com_locate_typeinfo(char *typelibname, php_com_dotnet_object *obj, char *dispname, int sink);
177174
int php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, int printdef, GUID *guid, int codepage);
175+
ITypeLib *php_com_cache_typelib(ITypeLib* TL, char *cache_key, zend_long cache_key_len);
176+
PHP_MINIT_FUNCTION(com_typeinfo);
177+
PHP_MSHUTDOWN_FUNCTION(com_typeinfo);
178178

179179
/* com_iterator.c */
180180
zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int by_ref);

0 commit comments

Comments
 (0)