Edit report at https://bugs.php.net/bug.php?id=48591&edit=1
ID: 48591
Comment by: register at cjsoft dot org
Reported by: pforsub at gmail dot com
Summary: Internal classes registered in extensions can cause
PHP crash
Status: Wont fix
Type: Bug
Package: Scripting Engine problem
Operating System: Windows 2008
PHP Version: 5.2.9
Assigned To: pajoye
Block user comment: N
Private report: N
New Comment:
The simpliest way to solve this bug without rebuild php itself (the binary
distribution for windows servers!):
INIT_CLASS_ENTRY(ce, "your_class", php_your_class_methods);
#ifdef WIN32
char *cn = (char*) emalloc(strlen(ce.name)+1);
strcpy(cn,ce.name);
free(ce.name);
ce.name = cn;
#endif
unix distribution don't need that path
Previous Comments:
------------------------------------------------------------------------
[2009-06-18 15:52:27] [email protected]
We do not support VC8 (2005) or VC9 (2008) for php 5.2 but VC6 SP6 with the
platform SDK 2003/02.
PHP 5.3 and later support VC9 SP1 (2008) with the SDK 6.1A.
------------------------------------------------------------------------
[2009-06-18 15:25:42] [email protected]
Without checking: I assume his code crates a memleak, and I think you will have
other issues when mixing different CRTs, Pierre, please confirm
------------------------------------------------------------------------
[2009-06-18 02:32:21] pforsub at gmail dot com
Description:
------------
Custom PHP extension compiled in Visual Studio 2005. (which means it is
compiled with CRT library msvcr80.dll)
Extension declares internal class for exception. PHP cause crash (0xc0000005
Access denied) during shutdown of execution.
Problem is that extension allocates string in its own CRT. This string used
then by php5ts without copying content of string (just using pointer). During
shutdown procedure extension is already unloaded, but php5ts tries to free
memory allocated in extension and cause crash.
Reproduce code:
---------------
Declaring exception in ZEND_MINIT_FUNCTION(myownextension):
zend_class_entry ce, *pce;
INIT_CLASS_ENTRY(ce, "MyOwnException", NULL);
pce = zend_register_internal_class_ex(&ce,
zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
Expected result:
----------------
Expected: No crash.
Proposed fix is:
--- Zend/zend_API.c Fri Mar 07 00:28:47 2008
+++ Zend/zend_API.c Thu Jun 18 08:40:53 2009
@@ -1992,6 +1992,7 @@
zend_class_entry *class_entry = malloc(sizeof(zend_class_entry));
char *lowercase_name = malloc(orig_class_entry->name_length + 1);
*class_entry = *orig_class_entry;
+ class_entry->name = strdup(orig_class_entry->name);
class_entry->type = ZEND_INTERNAL_CLASS;
zend_initialize_class_data(class_entry, 0 TSRMLS_CC);
Probably you should change also logic of INIT_CLASS_ENTRY macros to avoid
memory leak.
Actual result:
--------------
Crash occurs at the following call stack:
# ZEND_API void destroy_zend_class(zend_class_entry **pce)
# zend_hash_destroy(compiler_globals->class_table);
# static void compiler_globals_dtor(zend_compiler_globals *compiler_globals
TSRMLS_DC)
Line that cause exception is zend_opcode.c (200):
free(ce->name);
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=48591&edit=1