# [PATCH] fix pcre global variable abuse

- Thread: https://externals.io/message/9484
- Original archive: https://news-web.php.net/php.internals/9484
- Started by Joe Orton on 2004-04-22T10:02:18+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #9484 — Joe Orton — 2004-04-22T10:02:18+00:00

URL: https://externals.io/message/9484#9484

This fixes #121454: the pcre extension should not change the global
allocation callbacks for pcre.

PCRE is used inside httpd and may be used by modules other than PHP too;
having these modules use PHP allocation functions doesn't seem at all
sensible, and could mess up the memory limit accounting presumably.

The cause of #121454 is that during a restart, libphp4.so is unloaded
from memory, but the global variable pcre_malloc is left pointing at
php_pcre_malloc; so when httpd uses pcre, it all goes boom.

Alternative fix might be to use a shutdown function in the extension
which does "pcre_malloc = malloc; pcre_free = free;" but I think it's
wiser just to stay well clear of the issue.

--- php-4.3.6/ext/pcre/php_pcre.c.pcrealloc
+++ php-4.3.6/ext/pcre/php_pcre.c
@@ -47,20 +47,6 @@
 
 ZEND_DECLARE_MODULE_GLOBALS(pcre)
 
-
-static void *php_pcre_malloc(size_t size)
-{
-	return pemalloc(size, 1);
-}
-
-
-static void php_pcre_free(void *ptr)
-{
-	if (ptr)
-	pefree(ptr, 1);
-}
-
-
 static void php_free_pcre_cache(void *data)
 {
 	pcre_cache_entry *pce = (pcre_cache_entry *) data;
@@ -107,14 +93,6 @@
 	REGISTER_LONG_CONSTANT("PREG_SPLIT_OFFSET_CAPTURE", PREG_SPLIT_OFFSET_CAPTURE, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("PREG_GREP_INVERT", PREG_GREP_INVERT, CONST_CS | CONST_PERSISTENT);
 
-	pcre_malloc = php_pcre_malloc;
-	pcre_free = php_pcre_free;
-
-#ifdef NO_RECURSE
-	pcre_stack_malloc = php_pcre_malloc;
-	pcre_stack_free = php_pcre_free;
-#endif
-	
 	return SUCCESS;
 }
 /* }}} */
@@ -548,7 +526,7 @@
 					}
 				}
 
-				php_pcre_free((void *) stringlist);
+				pcre_free((void *) stringlist);
 			}
 		}
 		else { /* Failed to match */

---

## #9486 — Joe Orton — 2004-04-22T12:38:53+00:00

URL: https://externals.io/message/9484#9486 · In reply to: #9484

> This fixes #121454: the pcre extension should not change the global
> allocation callbacks for pcre.

Oops, wrong bug and even wrong bug database.  I meant #27810.

---

## #9498 — Andi Gutmans — 2004-04-23T14:01:21+00:00

URL: https://externals.io/message/9484#9498 · In reply to: #9484

I think changing back to malloc/free on RSHUTDOWN is a better solution. 
After all, we use our memory manager to prevent memory leaks and I think 
this is one of PHP's most important features. I don't trust third party 
extensions :)

Andi

At 11:02 AM 4/22/2004 +0100, Joe Orton wrote:
>This fixes #121454: the pcre extension should not change the global
>allocation callbacks for pcre.
>
>PCRE is used inside httpd and may be used by modules other than PHP too;
>having these modules use PHP allocation functions doesn't seem at all
>sensible, and could mess up the memory limit accounting presumably.
>
>The cause of #121454 is that during a restart, libphp4.so is unloaded
>from memory, but the global variable pcre_malloc is left pointing at
>php_pcre_malloc; so when httpd uses pcre, it all goes boom.
>
>Alternative fix might be to use a shutdown function in the extension
>which does "pcre_malloc = malloc; pcre_free = free;" but I think it's
>wiser just to stay well clear of the issue.
>
>--- php-4.3.6/ext/pcre/php_pcre.c.pcrealloc
>+++ php-4.3.6/ext/pcre/php_pcre.c
>@@ -47,20 +47,6 @@
>
>  ZEND_DECLARE_MODULE_GLOBALS(pcre)
>
>-
>-static void *php_pcre_malloc(size_t size)
>-{
>-       return pemalloc(size, 1);
>-}
>-
>-
>-static void php_pcre_free(void *ptr)
>-{
>-       if (ptr)
>-       pefree(ptr, 1);
>-}
>-
>-
>  static void php_free_pcre_cache(void *data)
>  {
>         pcre_cache_entry *pce = (pcre_cache_entry *) data;
>@@ -107,14 +93,6 @@
>         REGISTER_LONG_CONSTANT("PREG_SPLIT_OFFSET_CAPTURE", 
> PREG_SPLIT_OFFSET_CAPTURE, CONST_CS | CONST_PERSISTENT);
>         REGISTER_LONG_CONSTANT("PREG_GREP_INVERT", PREG_GREP_INVERT, 
> CONST_CS | CONST_PERSISTENT);
>
>-       pcre_malloc = php_pcre_malloc;
>-       pcre_free = php_pcre_free;
>-
>-#ifdef NO_RECURSE
>-       pcre_stack_malloc = php_pcre_malloc;
>-       pcre_stack_free = php_pcre_free;
>-#endif
>-
>         return SUCCESS;
>  }
>  /* }}} */
>@@ -548,7 +526,7 @@
>                                         }
>                                 }
>
>-                               php_pcre_free((void *) stringlist);
>+                               pcre_free((void *) stringlist);
>                         }
>                 }
>                 else { /* Failed to match */
