@@ -33,6 +33,8 @@ typedef struct {
33
33
int cflags ;
34
34
} reg_cache ;
35
35
36
+ static int reg_magic = 0 ;
37
+
36
38
/* {{{ _php_regcomp
37
39
*/
38
40
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)
42
44
reg_cache * rc = NULL ;
43
45
TSRMLS_FETCH ();
44
46
45
- if (zend_hash_find (& REG (ht_rc ), (char * ) pattern , patlen + 1 , (void * * ) & rc ) == FAILURE ||
46
- rc -> cflags != cflags ) {
47
- r = regcomp (preg , pattern , cflags );
48
- if (!r ) {
49
- reg_cache rcp ;
50
-
51
- rcp .cflags = cflags ;
52
- memcpy (& rcp .preg , preg , sizeof (* preg ));
53
- zend_hash_update (& REG (ht_rc ), (char * ) pattern , patlen + 1 ,
54
- (void * ) & rcp , sizeof (rcp ), NULL );
47
+ if (zend_hash_find (& REG (ht_rc ), (char * ) pattern , patlen + 1 , (void * * ) & rc ) == SUCCESS
48
+ && rc -> cflags == cflags ) {
49
+ /*
50
+ * We use a saved magic number to see whether cache is corrupted, and if it
51
+ * is, we flush it and compile the pattern from scratch.
52
+ */
53
+ if (rc -> preg .re_magic != reg_magic ) {
54
+ zend_hash_clean (& REG (ht_rc ));
55
+ } else {
56
+ memcpy (preg , & rc -> preg , sizeof (* preg ));
57
+ return r ;
55
58
}
56
- } else {
57
- memcpy (preg , & rc -> preg , sizeof (* preg ));
59
+ }
60
+
61
+ r = regcomp (preg , pattern , cflags );
62
+ if (!r ) {
63
+ reg_cache rcp ;
64
+
65
+ rcp .cflags = cflags ;
66
+ memcpy (& rcp .preg , preg , sizeof (* preg ));
67
+ /*
68
+ * Since we don't have access to the actual MAGIC1 definition in the private
69
+ * header file, we save the magic value immediately after compilation. Hopefully,
70
+ * it's good.
71
+ */
72
+ if (!reg_magic ) reg_magic = preg -> re_magic ;
73
+ zend_hash_update (& REG (ht_rc ), (char * ) pattern , patlen + 1 ,
74
+ (void * ) & rcp , sizeof (rcp ), NULL );
58
75
}
59
76
60
77
return r ;
0 commit comments