/* * get php_do_pcre_match */ int pcre_match (char * regex, char * subject) // {{{ { /* parameters */ pcre_cache_entry * pce; /* Compiled regular expression */ zend_string * regex_string; /* Regular expression */ zval * subpats = NULL; /* Array for subpatterns */ zval * matches; /* match counter */ zend_long start_offset = 0; /* Where the new search starts */ int return_val = -1; regex_string = ze_string_init (regex, STRLEN (regex), 0); #if PHP_VERSION_ID < 70300 if ( ZEND_SIZE_T_INT_OVFL (STRLEN (subject))) { php_error_docref (NULL, E_WARNING, "Subject is too long"); return -1; } #endif /* Compile regex or get it from cache. */ if ( (pce = pcre_get_compiled_regex_cache (regex_string) ) == NULL) { return -1; } zend_string_release (regex_string); matches = safe_emalloc (pce->capture_count + 1, sizeof (zval), 0); pce->refcount++; php_pcre_match_impl ( pce, subject, STRLEN (subject), matches, subpats, 0, 0, 0, start_offset ); pce->refcount--; if ( Z_TYPE_P (matches) != IS_LONG ) { kr_safe_efree (matches); return -1; } return_val = (int) Z_LVAL_P (matches); kr_safe_efree (matches); return return_val; } // }}}
static int oauth_provider_parse_auth_header(php_oauth_provider *sop, char *auth_header) /* {{{ */ { pcre_cache_entry *pce; zval subpats, return_value, *item_param, *current_param, *current_val; HashPosition hpos; zend_string *regex = zend_string_init(OAUTH_REGEX, sizeof(OAUTH_REGEX) - 1, 0); size_t decoded_len; if(!auth_header || strncasecmp(auth_header, "oauth", 4) || !sop) { return FAILURE; } /* pass "OAuth " */ auth_header += 5; if ((pce = pcre_get_compiled_regex_cache(regex)) == NULL) { zend_string_release(regex); return FAILURE; } zend_string_release(regex); ZVAL_NULL(&subpats); ZVAL_NULL(&return_value); php_pcre_match_impl( pce, auth_header, strlen(auth_header), &return_value, &subpats, 1, /* global */ 1, /* use flags */ 2, /* PREG_SET_ORDER */ 0 ); if (0 == Z_LVAL(return_value)) { return FAILURE; } zend_hash_internal_pointer_reset_ex(Z_ARRVAL(subpats), &hpos); /* walk the oauth param names */ do { if ((item_param = zend_hash_get_current_data_ex(Z_ARRVAL(subpats), &hpos)) != NULL) { zval decoded_val; char *tmp; /* * item = array( * 1 => param name * 2 => quoted value * 3 => unquoted value (defined if matched) * ) */ current_param = zend_hash_index_find(Z_ARRVAL_P(item_param), 1); if ((current_val =zend_hash_index_find(Z_ARRVAL_P(item_param), 3)) == NULL) { current_val = zend_hash_index_find(Z_ARRVAL_P(item_param), 2); } tmp = estrndup(Z_STRVAL_P(current_val), Z_STRLEN_P(current_val)); decoded_len = php_url_decode(tmp, Z_STRLEN_P(current_val)); ZVAL_STRINGL(&decoded_val, tmp, decoded_len); if (oauth_provider_set_param_value(sop->oauth_params, Z_STRVAL_P(current_param), &decoded_val)==FAILURE) { return FAILURE; } Z_DELREF(decoded_val); } } while (SUCCESS==zend_hash_move_forward_ex(Z_ARRVAL(subpats), &hpos)); zval_ptr_dtor(&return_value); zval_ptr_dtor(&subpats); return SUCCESS; }
zval *air_router_route(air_router_t *self) { zval *return_value; MAKE_STD_ZVAL(return_value); ZVAL_NULL(return_value); pcre_cache_entry *pce; HashTable *ht_or, *ht_cr; zval *original_rules, *compiled_rules, **entry, *r; zval *url; url = zend_read_property(air_router_ce, self, ZEND_STRL("_url"), 0 TSRMLS_CC); original_rules = zend_read_property(air_router_ce, self, ZEND_STRL("_original_rules"), 0 TSRMLS_CC); compiled_rules = zend_read_property(air_router_ce, self, ZEND_STRL("_compiled_rules"), 0 TSRMLS_CC); ht_or = Z_ARRVAL_P(original_rules); ht_cr = Z_ARRVAL_P(compiled_rules); for( /*zend_hash_internal_pointer_reset(ht_or)*/; zend_hash_has_more_elements(ht_or) == SUCCESS; zend_hash_move_forward(ht_or) ){ if (zend_hash_get_current_data(ht_or, (void**)&entry) == FAILURE) { continue; } char *key; uint key_len = 0; ulong idx = 0; smart_str ss = {0}; char *regex = NULL; uint regex_len = 0; //lazy compiling zend_hash_get_current_key_ex(ht_or, &key, &key_len, &idx, 0, NULL); r = air_arr_find(compiled_rules, key, key_len); if (r == NULL){ MAKE_STD_ZVAL(r); array_init(r); regex = air_router_compile(key, key_len, ®ex_len); char *ca = Z_STRVAL_PP(entry); int size = 0; while(size<Z_STRLEN_PP(entry)) { if(ca[size] == '.'){ break; } size++; } if(size==0){ add_assoc_stringl_ex(r, ZEND_STRS(air_c_key), ZEND_STRS("index"), 1); }else{ add_assoc_stringl_ex(r, ZEND_STRS(air_c_key), ca, size, 1); } if(size+1>=Z_STRLEN_PP(entry)){ add_assoc_stringl_ex(r, ZEND_STRS(air_a_key), ZEND_STRS("index"), 1); }else{ add_assoc_stringl_ex(r, ZEND_STRS(air_a_key), ca+size+1, Z_STRLEN_PP(entry)-size-1, 1); } add_assoc_zval_ex(compiled_rules, key, key_len, r); smart_str_appendc(&ss, '#'); smart_str_appendl(&ss, regex, regex_len-1); smart_str_appendc(&ss, '#'); smart_str_0(&ss); efree(regex); add_assoc_stringl_ex(r, ZEND_STRS("regex"), ss.c, ss.len, 1); }else{ zval *r_r = air_arr_find(r, ZEND_STRS("regex")); if (r_r == NULL){ continue; } smart_str_appendl(&ss, Z_STRVAL_P(r_r), Z_STRLEN_P(r_r)); smart_str_0(&ss); } if(ss.len > 0){ zval *ret; pce = pcre_get_compiled_regex_cache(ss.c, ss.len TSRMLS_CC); smart_str_free(&ss); if(pce){ zval matches, *subpats; MAKE_STD_ZVAL(subpats); ZVAL_NULL(subpats); php_pcre_match_impl(pce, Z_STRVAL_P(url), Z_STRLEN_P(url), &matches, subpats/* subpats */, 0/* global */, 0/* ZEND_NUM_ARGS() >= 4 */, 0/*flags PREG_OFFSET_CAPTURE*/, 0/* start_offset */ TSRMLS_CC); if (zend_hash_num_elements(Z_ARRVAL_P(subpats)) > 0) { ret = air_arr_del_index_el(subpats); air_router_route_apply_subpats(r, ret, ZEND_STRS(air_c_key), key, key_len); air_router_route_apply_subpats(r, ret, ZEND_STRS(air_a_key), key, key_len); ZVAL_ZVAL(return_value, ret, 1, 0); zval_ptr_dtor(&ret); zval_ptr_dtor(&subpats); //move forward specially zend_hash_move_forward(ht_or); break; } zval_ptr_dtor(&subpats); } } } return return_value; }