void phalcon_raw_url_encode(zval *return_value, zval *url) { zval copy; char *escaped; int use_copy = 0, length; if (Z_TYPE_P(url) == IS_STRING) { zend_make_printable_zval(url, ©, &use_copy); if (use_copy) { url = © } } escaped = php_raw_url_encode(Z_STRVAL_P(url), Z_STRLEN_P(url), &length); if (use_copy) { zval_dtor(url); } if (escaped) { RETURN_STRINGL(escaped, length, 0); } else { RETURN_NULL(); } }
PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen, int encode) { char *result; smart_str surl = {0}; smart_str buf = {0}; smart_str url_app = {0}; zend_string *encoded; smart_str_appendl(&surl, url, urllen); if (encode) { encoded = php_raw_url_encode(name, strlen(name)); smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); } else { smart_str_appends(&url_app, name); } smart_str_appendc(&url_app, '='); if (encode) { encoded = php_raw_url_encode(value, strlen(value)); smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); } else { smart_str_appends(&url_app, value); } append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output); smart_str_0(&buf); if (newlen) *newlen = ZSTR_LEN(buf.s); result = estrndup(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s)); smart_str_free(&url_app); smart_str_free(&buf); return result; }
/* {{{ php_url_encode_hash */ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, const char *num_prefix, int num_prefix_len, const char *key_prefix, int key_prefix_len, const char *key_suffix, int key_suffix_len, zval *type, char *arg_sep, int enc_type TSRMLS_DC) { char *key = NULL; char *ekey, *newprefix, *p; int arg_sep_len, ekey_len, key_type, newprefix_len; uint key_len; ulong idx; zval **zdata = NULL, *copyzval; if (!ht) { return FAILURE; } if (ht->nApplyCount > 0) { /* Prevent recursion */ return SUCCESS; } if (!arg_sep) { arg_sep = INI_STR("arg_separator.output"); if (!arg_sep || !strlen(arg_sep)) { arg_sep = URL_DEFAULT_ARG_SEP; } } arg_sep_len = strlen(arg_sep); for (zend_hash_internal_pointer_reset(ht); (key_type = zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, NULL)) != HASH_KEY_NON_EXISTANT; zend_hash_move_forward(ht) ) { if (key_type == HASH_KEY_IS_STRING && key_len && key[key_len-1] == '\0') { /* We don't want that trailing NULL */ key_len -= 1; } /* handling for private & protected object properties */ if (key && *key == '\0' && type != NULL) { const char *tmp; zend_object *zobj = zend_objects_get_address(type TSRMLS_CC); if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) != SUCCESS) { /* private or protected property access outside of the class */ continue; } zend_unmangle_property_name(key, key_len-1, &tmp, (const char**)&key); key_len = strlen(key); } if (zend_hash_get_current_data_ex(ht, (void **)&zdata, NULL) == FAILURE || !zdata || !(*zdata)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array"); return FAILURE; } if (Z_TYPE_PP(zdata) == IS_ARRAY || Z_TYPE_PP(zdata) == IS_OBJECT) { if (key_type == HASH_KEY_IS_STRING) { if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(key, key_len, &ekey_len); } else { ekey = php_url_encode(key, key_len, &ekey_len); } newprefix_len = key_suffix_len + ekey_len + key_prefix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, ekey, ekey_len); p += ekey_len; efree(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } else { /* Is an integer key */ ekey_len = spprintf(&ekey, 0, "%ld", idx); newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, num_prefix, num_prefix_len); p += num_prefix_len; memcpy(p, ekey, ekey_len); p += ekey_len; efree(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } ht->nApplyCount++; php_url_encode_hash_ex(HASH_OF(*zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_PP(zdata) == IS_OBJECT ? *zdata : NULL), arg_sep, enc_type TSRMLS_CC); ht->nApplyCount--; efree(newprefix); } else if (Z_TYPE_PP(zdata) == IS_NULL || Z_TYPE_PP(zdata) == IS_RESOURCE) { /* Skip these types */ continue; } else { if (formstr->len) { smart_str_appendl(formstr, arg_sep, arg_sep_len); } /* Simple key=value */ smart_str_appendl(formstr, key_prefix, key_prefix_len); if (key_type == HASH_KEY_IS_STRING) { if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(key, key_len, &ekey_len); } else { ekey = php_url_encode(key, key_len, &ekey_len); } smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } else { /* Numeric key */ if (num_prefix) { smart_str_appendl(formstr, num_prefix, num_prefix_len); } ekey_len = spprintf(&ekey, 0, "%ld", idx); smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } smart_str_appendl(formstr, key_suffix, key_suffix_len); smart_str_appendl(formstr, "=", 1); switch (Z_TYPE_PP(zdata)) { case IS_STRING: if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len); } else { ekey = php_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len); } break; case IS_LONG: case IS_BOOL: ekey_len = spprintf(&ekey, 0, "%ld", Z_LVAL_PP(zdata)); break; case IS_DOUBLE: ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_PP(zdata)); break; default: /* fall back on convert to string */ MAKE_STD_ZVAL(copyzval); *copyzval = **zdata; zval_copy_ctor(copyzval); convert_to_string_ex(©zval); if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len); } else { ekey = php_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len); } zval_ptr_dtor(©zval); } smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } } return SUCCESS; }
/* {{{ php_url_encode_hash */ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, const char *num_prefix, size_t num_prefix_len, const char *key_prefix, size_t key_prefix_len, const char *key_suffix, size_t key_suffix_len, zval *type, char *arg_sep, int enc_type) { zend_string *key = NULL; char *newprefix, *p; const char *prop_name; size_t arg_sep_len, newprefix_len, prop_len; zend_ulong idx; zval *zdata = NULL; if (!ht) { return FAILURE; } if (GC_IS_RECURSIVE(ht)) { /* Prevent recursion */ return SUCCESS; } if (!arg_sep) { arg_sep = INI_STR("arg_separator.output"); if (!arg_sep || !strlen(arg_sep)) { arg_sep = URL_DEFAULT_ARG_SEP; } } arg_sep_len = strlen(arg_sep); ZEND_HASH_FOREACH_KEY_VAL(ht, idx, key, zdata) { zend_bool is_dynamic = 1; if (Z_TYPE_P(zdata) == IS_INDIRECT) { zdata = Z_INDIRECT_P(zdata); if (Z_ISUNDEF_P(zdata)) { continue; } is_dynamic = 0; } /* handling for private & protected object properties */ if (key) { prop_name = ZSTR_VAL(key); prop_len = ZSTR_LEN(key); if (type != NULL && zend_check_property_access(Z_OBJ_P(type), key, is_dynamic) != SUCCESS) { /* property not visible in this scope */ continue; } if (ZSTR_VAL(key)[0] == '\0' && type != NULL) { const char *tmp; zend_unmangle_property_name_ex(key, &tmp, &prop_name, &prop_len); } else { prop_name = ZSTR_VAL(key); prop_len = ZSTR_LEN(key); } } else { prop_name = NULL; prop_len = 0; } ZVAL_DEREF(zdata); if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) { if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } newprefix_len = key_suffix_len + ZSTR_LEN(ekey) + key_prefix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, ZSTR_VAL(ekey), ZSTR_LEN(ekey)); p += ZSTR_LEN(ekey); zend_string_free(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } else { char *ekey; size_t ekey_len; /* Is an integer key */ ekey_len = spprintf(&ekey, 0, ZEND_LONG_FMT, idx); newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, num_prefix, num_prefix_len); p += num_prefix_len; memcpy(p, ekey, ekey_len); p += ekey_len; efree(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { GC_PROTECT_RECURSION(ht); } php_url_encode_hash_ex(HASH_OF(zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_P(zdata) == IS_OBJECT ? zdata : NULL), arg_sep, enc_type); if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { GC_UNPROTECT_RECURSION(ht); } efree(newprefix); } else if (Z_TYPE_P(zdata) == IS_NULL || Z_TYPE_P(zdata) == IS_RESOURCE) { /* Skip these types */ continue; } else { if (formstr->s) { smart_str_appendl(formstr, arg_sep, arg_sep_len); } /* Simple key=value */ smart_str_appendl(formstr, key_prefix, key_prefix_len); if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } smart_str_append(formstr, ekey); zend_string_free(ekey); } else { /* Numeric key */ if (num_prefix) { smart_str_appendl(formstr, num_prefix, num_prefix_len); } smart_str_append_long(formstr, idx); } smart_str_appendl(formstr, key_suffix, key_suffix_len); smart_str_appendl(formstr, "=", 1); switch (Z_TYPE_P(zdata)) { case IS_STRING: { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } else { ekey = php_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } smart_str_append(formstr, ekey); zend_string_free(ekey); } break; case IS_LONG: smart_str_append_long(formstr, Z_LVAL_P(zdata)); break; case IS_FALSE: smart_str_appendl(formstr, "0", sizeof("0")-1); break; case IS_TRUE: smart_str_appendl(formstr, "1", sizeof("1")-1); break; case IS_DOUBLE: { char *ekey; size_t ekey_len; ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_P(zdata)); smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } break; default: { zend_string *ekey; zend_string *tmp; zend_string *str= zval_get_tmp_string(zdata, &tmp); if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(ZSTR_VAL(str), ZSTR_LEN(str)); } else { ekey = php_url_encode(ZSTR_VAL(str), ZSTR_LEN(str)); } smart_str_append(formstr, ekey); zend_tmp_string_release(tmp); zend_string_free(ekey); } } } } ZEND_HASH_FOREACH_END();
/* {{{ php_url_encode_hash */ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, const char *num_prefix, size_t num_prefix_len, const char *key_prefix, size_t key_prefix_len, const char *key_suffix, size_t key_suffix_len, zval *type, char *arg_sep, int enc_type) { zend_string *key = NULL; char *newprefix, *p; const char *prop_name; size_t arg_sep_len, newprefix_len, prop_len; zend_ulong idx; zval *zdata = NULL, copyzval; if (!ht) { return FAILURE; } if (ht->u.v.nApplyCount > 0) { /* Prevent recursion */ return SUCCESS; } if (!arg_sep) { arg_sep = INI_STR("arg_separator.output"); if (!arg_sep || !strlen(arg_sep)) { arg_sep = URL_DEFAULT_ARG_SEP; } } arg_sep_len = strlen(arg_sep); ZEND_HASH_FOREACH_KEY_VAL_IND(ht, idx, key, zdata) { /* handling for private & protected object properties */ if (key) { if (key->val[0] == '\0' && type != NULL) { const char *tmp; zend_object *zobj = Z_OBJ_P(type); if (zend_check_property_access(zobj, key) != SUCCESS) { /* private or protected property access outside of the class */ continue; } zend_unmangle_property_name_ex(key, &tmp, &prop_name, &prop_len); } else { prop_name = key->val; prop_len = key->len; } } else { prop_name = NULL; prop_len = 0; } ZVAL_DEREF(zdata); if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) { if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } newprefix_len = key_suffix_len + ekey->len + key_prefix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, ekey->val, ekey->len); p += ekey->len; zend_string_free(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } else { char *ekey; size_t ekey_len; /* Is an integer key */ ekey_len = spprintf(&ekey, 0, "%pd", idx); newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, num_prefix, num_prefix_len); p += num_prefix_len; memcpy(p, ekey, ekey_len); p += ekey_len; efree(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } if (ZEND_HASH_APPLY_PROTECTION(ht)) { ht->u.v.nApplyCount++; } php_url_encode_hash_ex(HASH_OF(zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_P(zdata) == IS_OBJECT ? zdata : NULL), arg_sep, enc_type); if (ZEND_HASH_APPLY_PROTECTION(ht)) { ht->u.v.nApplyCount--; } efree(newprefix); } else if (Z_TYPE_P(zdata) == IS_NULL || Z_TYPE_P(zdata) == IS_RESOURCE) { /* Skip these types */ continue; } else { if (formstr->s) { smart_str_appendl(formstr, arg_sep, arg_sep_len); } /* Simple key=value */ smart_str_appendl(formstr, key_prefix, key_prefix_len); if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } smart_str_append(formstr, ekey); zend_string_free(ekey); } else { /* Numeric key */ if (num_prefix) { smart_str_appendl(formstr, num_prefix, num_prefix_len); } smart_str_append_long(formstr, idx); } smart_str_appendl(formstr, key_suffix, key_suffix_len); smart_str_appendl(formstr, "=", 1); switch (Z_TYPE_P(zdata)) { case IS_STRING: { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } else { ekey = php_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } smart_str_append(formstr, ekey); zend_string_free(ekey); } break; case IS_LONG: smart_str_append_long(formstr, Z_LVAL_P(zdata)); break; case IS_FALSE: smart_str_appendl(formstr, "0", sizeof("0")-1); break; case IS_TRUE: smart_str_appendl(formstr, "1", sizeof("1")-1); break; case IS_DOUBLE: { char *ekey; size_t ekey_len; ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_P(zdata)); smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } break; default: { zend_string *ekey; /* fall back on convert to string */ ZVAL_DUP(©zval, zdata); convert_to_string_ex(©zval); if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL(copyzval), Z_STRLEN(copyzval)); } else { ekey = php_url_encode(Z_STRVAL(copyzval), Z_STRLEN(copyzval)); } smart_str_append(formstr, ekey); zval_ptr_dtor(©zval); zend_string_free(ekey); } } } } ZEND_HASH_FOREACH_END(); return SUCCESS; }
static inline int php_url_scanner_reset_var_impl(zend_string *name, int encode, int type) { char *start, *end, *limit; size_t separator_len; smart_str sname = {0}; smart_str hname = {0}; smart_str url_app = {0}; smart_str form_app = {0}; zend_string *encoded; int ret = SUCCESS; zend_bool sep_removed = 0; url_adapt_state_ex_t *url_state; if (type) { url_state = &BG(url_adapt_session_ex); } else { url_state = &BG(url_adapt_output_ex); } /* Short circuit check. Only check url_app. */ if (!url_state->url_app.s || !ZSTR_LEN(url_state->url_app.s)) { return SUCCESS; } if (encode) { encoded = php_raw_url_encode(ZSTR_VAL(name), ZSTR_LEN(name)); smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); encoded = php_escape_html_entities_ex((unsigned char *)ZSTR_VAL(name), ZSTR_LEN(name), 0, ENT_QUOTES|ENT_SUBSTITUTE, SG(default_charset), 0); smart_str_appendl(&hname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); } else { smart_str_appendl(&sname, ZSTR_VAL(name), ZSTR_LEN(name)); smart_str_appendl(&hname, ZSTR_VAL(name), ZSTR_LEN(name)); } smart_str_0(&sname); smart_str_0(&hname); smart_str_append_smart_str(&url_app, &sname); smart_str_appendc(&url_app, '='); smart_str_0(&url_app); smart_str_appends(&form_app, "<input type=\"hidden\" name=\""); smart_str_append_smart_str(&form_app, &hname); smart_str_appends(&form_app, "\" value=\""); smart_str_0(&form_app); /* Short circuit check. Only check url_app. */ start = (char *) php_memnstr(ZSTR_VAL(url_state->url_app.s), ZSTR_VAL(url_app.s), ZSTR_LEN(url_app.s), ZSTR_VAL(url_state->url_app.s) + ZSTR_LEN(url_state->url_app.s)); if (!start) { ret = FAILURE; goto finish; } /* Get end of url var */ limit = ZSTR_VAL(url_state->url_app.s) + ZSTR_LEN(url_state->url_app.s); end = start + ZSTR_LEN(url_app.s); separator_len = strlen(PG(arg_separator).output); while (end < limit) { if (!memcmp(end, PG(arg_separator).output, separator_len)) { end += separator_len; sep_removed = 1; break; } end++; } /* Remove all when this is the only rewrite var */ if (ZSTR_LEN(url_state->url_app.s) == end - start) { php_url_scanner_reset_vars_impl(type); goto finish; } /* Check preceeding separator */ if (!sep_removed && start - PG(arg_separator).output >= separator_len && !memcmp(start - separator_len, PG(arg_separator).output, separator_len)) { start -= separator_len; } /* Remove partially */ memmove(start, end, ZSTR_LEN(url_state->url_app.s) - (end - ZSTR_VAL(url_state->url_app.s))); ZSTR_LEN(url_state->url_app.s) -= end - start; ZSTR_VAL(url_state->url_app.s)[ZSTR_LEN(url_state->url_app.s)] = '\0'; /* Remove form var */ start = (char *) php_memnstr(ZSTR_VAL(url_state->form_app.s), ZSTR_VAL(form_app.s), ZSTR_LEN(form_app.s), ZSTR_VAL(url_state->form_app.s) + ZSTR_LEN(url_state->form_app.s)); if (!start) { /* Should not happen */ ret = FAILURE; php_url_scanner_reset_vars_impl(type); goto finish; } /* Get end of form var */ limit = ZSTR_VAL(url_state->form_app.s) + ZSTR_LEN(url_state->form_app.s); end = start + ZSTR_LEN(form_app.s); while (end < limit) { if (*end == '>') { end += 1; break; } end++; } /* Remove partially */ memmove(start, end, ZSTR_LEN(url_state->form_app.s) - (end - ZSTR_VAL(url_state->form_app.s))); ZSTR_LEN(url_state->form_app.s) -= end - start; ZSTR_VAL(url_state->form_app.s)[ZSTR_LEN(url_state->form_app.s)] = '\0'; finish: smart_str_free(&url_app); smart_str_free(&form_app); smart_str_free(&sname); smart_str_free(&hname); return ret; }
static inline int php_url_scanner_add_var_impl(char *name, size_t name_len, char *value, size_t value_len, int encode, int type) { smart_str sname = {0}; smart_str svalue = {0}; smart_str hname = {0}; smart_str hvalue = {0}; zend_string *encoded; url_adapt_state_ex_t *url_state; php_output_handler_func_t handler; if (type) { url_state = &BG(url_adapt_session_ex); handler = php_url_scanner_session_handler; } else { url_state = &BG(url_adapt_output_ex); handler = php_url_scanner_output_handler; } if (!url_state->active) { php_url_scanner_ex_activate(type); php_output_start_internal(ZEND_STRL("URL-Rewriter"), handler, 0, PHP_OUTPUT_HANDLER_STDFLAGS); url_state->active = 1; } if (url_state->url_app.s && ZSTR_LEN(url_state->url_app.s) != 0) { smart_str_appends(&url_state->url_app, PG(arg_separator).output); } if (encode) { encoded = php_raw_url_encode(name, name_len); smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); encoded = php_raw_url_encode(value, value_len); smart_str_appendl(&svalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); encoded = php_escape_html_entities_ex((unsigned char*)name, name_len, 0, ENT_QUOTES|ENT_SUBSTITUTE, SG(default_charset), 0); smart_str_appendl(&hname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); encoded = php_escape_html_entities_ex((unsigned char*)value, value_len, 0, ENT_QUOTES|ENT_SUBSTITUTE, SG(default_charset), 0); smart_str_appendl(&hvalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); } else { smart_str_appendl(&sname, name, name_len); smart_str_appendl(&svalue, value, value_len); smart_str_appendl(&hname, name, name_len); smart_str_appendl(&hvalue, value, value_len); } smart_str_append_smart_str(&url_state->url_app, &sname); smart_str_appendc(&url_state->url_app, '='); smart_str_append_smart_str(&url_state->url_app, &svalue); smart_str_appends(&url_state->form_app, "<input type=\"hidden\" name=\""); smart_str_append_smart_str(&url_state->form_app, &hname); smart_str_appends(&url_state->form_app, "\" value=\""); smart_str_append_smart_str(&url_state->form_app, &hvalue); smart_str_appends(&url_state->form_app, "\" />"); smart_str_free(&sname); smart_str_free(&svalue); smart_str_free(&hname); smart_str_free(&hvalue); return SUCCESS; }