summaryrefslogtreecommitdiff
path: root/ext/ereg/ereg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ereg/ereg.c')
-rw-r--r--ext/ereg/ereg.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/ext/ereg/ereg.c b/ext/ereg/ereg.c
index 02d1903539..c8afdc80f9 100644
--- a/ext/ereg/ereg.c
+++ b/ext/ereg/ereg.c
@@ -33,6 +33,8 @@ typedef struct {
int cflags;
} reg_cache;
+static int reg_magic = 0;
+
/* {{{ _php_regcomp
*/
static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
@@ -42,19 +44,34 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
reg_cache *rc = NULL;
TSRMLS_FETCH();
- if(zend_hash_find(&REG(ht_rc), (char *) pattern, patlen+1, (void **) &rc) == FAILURE ||
- rc->cflags != cflags) {
- r = regcomp(preg, pattern, cflags);
- if(!r) {
- reg_cache rcp;
-
- rcp.cflags = cflags;
- memcpy(&rcp.preg, preg, sizeof(*preg));
- zend_hash_update(&REG(ht_rc), (char *) pattern, patlen+1,
- (void *) &rcp, sizeof(rcp), NULL);
+ if(zend_hash_find(&REG(ht_rc), (char *) pattern, patlen+1, (void **) &rc) == SUCCESS
+ && rc->cflags == cflags) {
+ /*
+ * We use a saved magic number to see whether cache is corrupted, and if it
+ * is, we flush it and compile the pattern from scratch.
+ */
+ if (rc->preg.re_magic != reg_magic) {
+ zend_hash_clean(&REG(ht_rc));
+ } else {
+ memcpy(preg, &rc->preg, sizeof(*preg));
+ return r;
}
- } else {
- memcpy(preg, &rc->preg, sizeof(*preg));
+ }
+
+ r = regcomp(preg, pattern, cflags);
+ if(!r) {
+ reg_cache rcp;
+
+ rcp.cflags = cflags;
+ memcpy(&rcp.preg, preg, sizeof(*preg));
+ /*
+ * Since we don't have access to the actual MAGIC1 definition in the private
+ * header file, we save the magic value immediately after compilation. Hopefully,
+ * it's good.
+ */
+ if (!reg_magic) reg_magic = preg->re_magic;
+ zend_hash_update(&REG(ht_rc), (char *) pattern, patlen+1,
+ (void *) &rcp, sizeof(rcp), NULL);
}
return r;