mirror of
https://github.com/php/php-src.git
synced 2024-11-25 19:05:31 +08:00
MFH: Fix bug #48416 - Force a cache size for ereg to stop it getting out of control. Lazy LRU here.
This commit is contained in:
parent
19194ff51b
commit
4044f880e8
@ -67,8 +67,10 @@ const zend_function_entry ereg_functions[] = {
|
||||
typedef struct {
|
||||
regex_t preg;
|
||||
int cflags;
|
||||
unsigned long lastuse;
|
||||
} reg_cache;
|
||||
static int reg_magic = 0;
|
||||
#define EREG_CACHE_SIZE 4096
|
||||
/* }}} */
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(ereg)
|
||||
@ -88,6 +90,38 @@ zend_module_entry ereg_module_entry = {
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ereg_lru_cmp */
|
||||
static int ereg_lru_cmp(const void *a, const void *b TSRMLS_DC)
|
||||
{
|
||||
Bucket *f = *((Bucket **) a);
|
||||
Bucket *s = *((Bucket **) b);
|
||||
|
||||
if (((reg_cache *)f->pData)->lastuse <
|
||||
((reg_cache *)s->pData)->lastuse) {
|
||||
return -1;
|
||||
} else if (((reg_cache *)f->pData)->lastuse ==
|
||||
((reg_cache *)s->pData)->lastuse) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ static ereg_clean_cache */
|
||||
static int ereg_clean_cache(void *data, void *arg TSRMLS_DC)
|
||||
{
|
||||
int *num_clean = (int *)arg;
|
||||
|
||||
if (*num_clean > 0) {
|
||||
(*num_clean)--;
|
||||
return ZEND_HASH_APPLY_REMOVE;
|
||||
} else {
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ _php_regcomp
|
||||
*/
|
||||
static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
|
||||
@ -96,7 +130,18 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
|
||||
int patlen = strlen(pattern);
|
||||
reg_cache *rc = NULL;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
|
||||
if (zend_hash_num_elements(&EREG(ht_rc)) >= EREG_CACHE_SIZE) {
|
||||
/* easier than dealing with overflow as it happens */
|
||||
if (EREG(lru_counter) >= (1 << 31) || zend_hash_sort(&EREG(ht_rc), zend_qsort, ereg_lru_cmp, 0 TSRMLS_CC) == FAILURE) {
|
||||
zend_hash_clean(&EREG(ht_rc));
|
||||
EREG(lru_counter) = 0;
|
||||
} else {
|
||||
int num_clean = EREG_CACHE_SIZE / 4;
|
||||
zend_hash_apply_with_argument(&EREG(ht_rc), ereg_clean_cache, &num_clean TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
if(zend_hash_find(&EREG(ht_rc), (char *) pattern, patlen+1, (void **) &rc) == SUCCESS
|
||||
&& rc->cflags == cflags) {
|
||||
#ifdef HAVE_REGEX_T_RE_MAGIC
|
||||
@ -106,6 +151,7 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
|
||||
*/
|
||||
if (rc->preg.re_magic != reg_magic) {
|
||||
zend_hash_clean(&EREG(ht_rc));
|
||||
EREG(lru_counter) = 0;
|
||||
} else {
|
||||
memcpy(preg, &rc->preg, sizeof(*preg));
|
||||
return r;
|
||||
@ -117,6 +163,7 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
|
||||
reg_cache rcp;
|
||||
|
||||
rcp.cflags = cflags;
|
||||
rcp.lastuse = ++(EREG(lru_counter));
|
||||
memcpy(&rcp.preg, preg, sizeof(*preg));
|
||||
/*
|
||||
* Since we don't have access to the actual MAGIC1 definition in the private
|
||||
@ -135,6 +182,7 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
|
||||
reg_cache rcp;
|
||||
|
||||
rcp.cflags = cflags;
|
||||
rcp.lastuse = ++(EREG(lru_counter));
|
||||
memcpy(&rcp.preg, preg, sizeof(*preg));
|
||||
zend_hash_update(&EREG(ht_rc), (char *) pattern, patlen+1,
|
||||
(void *) &rcp, sizeof(rcp), NULL);
|
||||
@ -158,6 +206,7 @@ static void _free_ereg_cache(reg_cache *rc)
|
||||
static void php_ereg_init_globals(zend_ereg_globals *ereg_globals TSRMLS_DC)
|
||||
{
|
||||
zend_hash_init(&ereg_globals->ht_rc, 0, NULL, (void (*)(void *)) _free_ereg_cache, 1);
|
||||
ereg_globals->lru_counter = 0;
|
||||
}
|
||||
|
||||
static void php_ereg_destroy_globals(zend_ereg_globals *ereg_globals TSRMLS_DC)
|
||||
|
@ -39,6 +39,7 @@ PHPAPI PHP_FUNCTION(sql_regcase);
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(ereg)
|
||||
HashTable ht_rc;
|
||||
unsigned int lru_counter;
|
||||
ZEND_END_MODULE_GLOBALS(ereg)
|
||||
|
||||
/* Module functions */
|
||||
|
Loading…
Reference in New Issue
Block a user