PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - lcov_data/ext/standard - url_scanner_ex.re (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 382 464 82.3 %
Date: 2022-01-16 Functions: 34 37 91.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2018 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt                                  |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Author: Sascha Schumann <sascha@schumann.cx>                         |
      16             :   |         Yasuo Ohgaki <yohgaki@ohgaki.net>                            |
      17             :   +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #include "php.h"
      23             : 
      24             : #ifdef HAVE_UNISTD_H
      25             : #include <unistd.h>
      26             : #endif
      27             : #ifdef HAVE_LIMITS_H
      28             : #include <limits.h>
      29             : #endif
      30             : 
      31             : #include <stdio.h>
      32             : #include <stdlib.h>
      33             : #include <string.h>
      34             : 
      35             : #include "SAPI.h"
      36             : #include "php_ini.h"
      37             : #include "php_globals.h"
      38             : #include "php_string.h"
      39             : #define STATE_TAG SOME_OTHER_STATE_TAG
      40             : #include "basic_functions.h"
      41             : #include "url.h"
      42             : #include "html.h"
      43             : #undef STATE_TAG
      44             : 
      45             : #define url_scanner url_scanner_ex
      46             : 
      47             : #include "zend_smart_str.h"
      48             : 
      49      124291 : static void tag_dtor(zval *zv)
      50             : {
      51      124291 :         free(Z_PTR_P(zv));
      52      124291 : }
      53             : 
      54       49606 : static int php_ini_on_update_tags(zend_ini_entry *entry, zend_string *new_value, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage, int type)
      55             : {
      56             :         url_adapt_state_ex_t *ctx;
      57             :         char *key;
      58             :         char *tmp;
      59       49606 :         char *lasts = NULL;
      60             : 
      61       49606 :         if (type) {
      62       24801 :                 ctx = &BG(url_adapt_session_ex);
      63             :         } else {
      64       24805 :                 ctx = &BG(url_adapt_output_ex);
      65             :         }
      66             : 
      67       49606 :         tmp = estrndup(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
      68             : 
      69       49606 :         if (ctx->tags)
      70           4 :                 zend_hash_destroy(ctx->tags);
      71             :         else {
      72       49602 :                 ctx->tags = malloc(sizeof(HashTable));
      73       49602 :                 if (!ctx->tags) {
      74           0 :                         efree(tmp);
      75           0 :                         return FAILURE;
      76             :                 }
      77             :         }
      78             : 
      79       49606 :         zend_hash_init(ctx->tags, 0, NULL, tag_dtor, 1);
      80             : 
      81      223293 :         for (key = php_strtok_r(tmp, ",", &lasts);
      82             :                  key;
      83      124081 :                  key = php_strtok_r(NULL, ",", &lasts)) {
      84             :                 char *val;
      85             : 
      86      124081 :                 val = strchr(key, '=');
      87      124081 :                 if (val) {
      88             :                         char *q;
      89             :                         size_t keylen;
      90             : 
      91      124081 :                         *val++ = '\0';
      92      570783 :                         for (q = key; *q; q++) {
      93      446702 :                                 *q = tolower(*q);
      94             :                         }
      95      124081 :                         keylen = q - key;
      96      124081 :                         zend_hash_str_add_mem(ctx->tags, key, keylen, val, strlen(val)+1);
      97             :                 }
      98             :         }
      99             : 
     100       49606 :         efree(tmp);
     101             : 
     102       49606 :         return SUCCESS;
     103             : }
     104             : 
     105       24801 : static PHP_INI_MH(OnUpdateSessionTags)
     106             : {
     107       24801 :         return php_ini_on_update_tags(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage, 1);
     108             : }
     109             : 
     110       24805 : static PHP_INI_MH(OnUpdateOutputTags)
     111             : {
     112       24805 :         return php_ini_on_update_tags(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage, 0);
     113             : }
     114             : 
     115       49620 : static int php_ini_on_update_hosts(zend_ini_entry *entry, zend_string *new_value, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage, int type)
     116             : {
     117             :         HashTable *hosts;
     118             :         char *key;
     119             :         char *tmp;
     120       49620 :         char *lasts = NULL;
     121             : 
     122       49620 :         if (type) {
     123       24811 :                 hosts = &BG(url_adapt_session_hosts_ht);
     124             :         } else {
     125       24809 :                 hosts = &BG(url_adapt_output_hosts_ht);
     126             :         }
     127       49620 :         zend_hash_clean(hosts);
     128             : 
     129             :         /* Use user supplied host whitelist */
     130       49620 :         tmp = estrndup(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
     131       99254 :         for (key = php_strtok_r(tmp, ",", &lasts);
     132             :                  key;
     133          14 :                  key = php_strtok_r(NULL, ",", &lasts)) {
     134             :                 size_t keylen;
     135             :                 zend_string *tmp_key;
     136             :                 char *q;
     137             : 
     138         140 :                 for (q = key; *q; q++) {
     139         126 :                         *q = tolower(*q);
     140             :                 }
     141          14 :                 keylen = q - key;
     142          14 :                 if (keylen > 0) {
     143          14 :                         tmp_key = zend_string_init(key, keylen, 0);
     144          14 :                         zend_hash_add_empty_element(hosts, tmp_key);
     145             :                         zend_string_release(tmp_key);
     146             :                 }
     147             :         }
     148       49620 :         efree(tmp);
     149             : 
     150       49620 :         return SUCCESS;
     151             : }
     152             : 
     153       24811 : static PHP_INI_MH(OnUpdateSessionHosts)
     154             : {
     155       24811 :         return php_ini_on_update_hosts(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage, 1);
     156             : }
     157             : 
     158       24809 : static PHP_INI_MH(OnUpdateOutputHosts)
     159             : {
     160       24809 :         return php_ini_on_update_hosts(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage, 0);
     161             : }
     162             : 
     163             : /* FIXME: OnUpdate*Hosts cannot set default to $_SERVER['HTTP_HOST'] at startup */
     164             : PHP_INI_BEGIN()
     165             :         STD_PHP_INI_ENTRY("session.trans_sid_tags", "a=href,area=href,frame=src,form=", PHP_INI_ALL, OnUpdateSessionTags, url_adapt_session_ex, php_basic_globals, basic_globals)
     166             :         STD_PHP_INI_ENTRY("session.trans_sid_hosts", "", PHP_INI_ALL, OnUpdateSessionHosts, url_adapt_session_hosts_ht, php_basic_globals, basic_globals)
     167             :         STD_PHP_INI_ENTRY("url_rewriter.tags", "form=", PHP_INI_ALL, OnUpdateOutputTags, url_adapt_session_ex, php_basic_globals, basic_globals)
     168             :         STD_PHP_INI_ENTRY("url_rewriter.hosts", "", PHP_INI_ALL, OnUpdateOutputHosts, url_adapt_session_hosts_ht, php_basic_globals, basic_globals)
     169             : PHP_INI_END()
     170             : 
     171             : /*!re2c
     172             : any = [\000-\377];
     173             : N = (any\[<]);
     174             : alpha = [a-zA-Z];
     175             : alphanamespace = [a-zA-Z:];
     176             : alphadash = ([a-zA-Z] | "-");
     177             : */
     178             : 
     179             : #define YYFILL(n) goto done
     180             : #define YYCTYPE unsigned char
     181             : #define YYCURSOR p
     182             : #define YYLIMIT q
     183             : #define YYMARKER r
     184             : 
     185         316 : static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator)
     186             : {
     187             :         php_url *url_parts;
     188             :         char *tmp;
     189             :         size_t tmp_len;
     190             : 
     191             :         smart_str_0(url); /* FIXME: Bug #70480 php_url_parse_ex() crashes by processing chars exceed len */
     192         316 :         url_parts = php_url_parse_ex(ZSTR_VAL(url->s), ZSTR_LEN(url->s));
     193             : 
     194             :         /* Ignore malformed URLs */
     195         316 :         if (!url_parts) {
     196             :                 smart_str_append_smart_str(dest, url);
     197           0 :                 return;
     198             :         }
     199             : 
     200             :         /* Don't modify URLs of the format "#mark" */
     201         316 :         if (url_parts->fragment && '#' == ZSTR_VAL(url->s)[0]) {
     202             :                 smart_str_append_smart_str(dest, url);
     203           1 :                 php_url_free(url_parts);
     204           1 :                 return;
     205             :         }
     206             : 
     207             :         /* Check protocol. Only http/https is allowed. */
     208         315 :         if (url_parts->scheme
     209         122 :                 && strcasecmp("http", url_parts->scheme)
     210          56 :                 && strcasecmp("https", url_parts->scheme)) {
     211             :                 smart_str_append_smart_str(dest, url);
     212          14 :                 php_url_free(url_parts);
     213          14 :                 return;
     214             :         }
     215             : 
     216             :         /* Check host whitelist. If it's not listed, do nothing. */
     217         301 :         if (url_parts->host
     218         187 :                 && (tmp_len = strlen(url_parts->host))
     219         187 :                 && (tmp = php_strtolower(url_parts->host, tmp_len))
     220         187 :                 && !zend_hash_str_find(&BG(url_adapt_session_hosts_ht), tmp, tmp_len)) {
     221             :                 smart_str_append_smart_str(dest, url);
     222         117 :                 php_url_free(url_parts);
     223         117 :                 return;
     224             :         }
     225             : 
     226             :         /*
     227             :          * When URL does not have path and query string add "/?".
     228             :          * i.e. If URL is only "?foo=bar", should not add "/?".
     229             :          */
     230         184 :         if (!url_parts->path && !url_parts->query && !url_parts->fragment) {
     231             :                 /* URL is http://php.net or like */
     232             :                 smart_str_append_smart_str(dest, url);
     233             :                 smart_str_appendc(dest, '/');
     234             :                 smart_str_appendc(dest, '?');
     235             :                 smart_str_append_smart_str(dest, url_app);
     236           4 :                 php_url_free(url_parts);
     237           4 :                 return;
     238             :         }
     239             : 
     240         180 :         if (url_parts->scheme) {
     241          36 :                 smart_str_appends(dest, url_parts->scheme);
     242             :                 smart_str_appends(dest, "://");
     243         144 :         } else if (*(ZSTR_VAL(url->s)) == '/' && *(ZSTR_VAL(url->s)+1) == '/') {
     244             :                 smart_str_appends(dest, "//");
     245             :         }
     246         180 :         if (url_parts->user) {
     247           0 :                 smart_str_appends(dest, url_parts->user);
     248           0 :                 if (url_parts->pass) {
     249           0 :                         smart_str_appends(dest, url_parts->pass);
     250             :                         smart_str_appendc(dest, ':');
     251             :                 }
     252             :                 smart_str_appendc(dest, '@');
     253             :         }
     254         180 :         if (url_parts->host) {
     255          66 :                                 smart_str_appends(dest, url_parts->host);
     256             :         }
     257         180 :         if (url_parts->port) {
     258             :                 smart_str_appendc(dest, ':');
     259           6 :                 smart_str_append_unsigned(dest, (long)url_parts->port);
     260             :         }
     261         180 :         if (url_parts->path) {
     262         175 :                 smart_str_appends(dest, url_parts->path);
     263             :         }
     264             :         smart_str_appendc(dest, '?');
     265         180 :         if (url_parts->query) {
     266          83 :                 smart_str_appends(dest, url_parts->query);
     267          83 :                 smart_str_appends(dest, separator);
     268             :                 smart_str_append_smart_str(dest, url_app);
     269             :         } else {
     270             :                 smart_str_append_smart_str(dest, url_app);
     271             :         }
     272         180 :         if (url_parts->fragment) {
     273             :                 smart_str_appendc(dest, '#');
     274          46 :                 smart_str_appends(dest, url_parts->fragment);
     275             :         }
     276         180 :         php_url_free(url_parts);
     277             : }
     278             : 
     279             : enum {
     280             :         TAG_NORMAL = 0,
     281             :         TAG_FORM
     282             : };
     283             : 
     284             : enum {
     285             :         ATTR_NORMAL = 0,
     286             :         ATTR_ACTION
     287             : };
     288             : 
     289             : #undef YYFILL
     290             : #undef YYCTYPE
     291             : #undef YYCURSOR
     292             : #undef YYLIMIT
     293             : #undef YYMARKER
     294             : 
     295         530 : static inline void tag_arg(url_adapt_state_ex_t *ctx, char quotes, char type)
     296             : {
     297         530 :         char f = 0;
     298             : 
     299             :         /* arg.s is string WITHOUT NUL.
     300             :            To avoid partial match, NUL is added here */
     301         530 :         ZSTR_VAL(ctx->arg.s)[ZSTR_LEN(ctx->arg.s)] = '\0';
     302         530 :         if (!strcasecmp(ZSTR_VAL(ctx->arg.s), ctx->lookup_data)) {
     303         316 :                 f = 1;
     304             :         }
     305             : 
     306         530 :         if (quotes) {
     307         525 :                 smart_str_appendc(&ctx->result, type);
     308             :         }
     309         530 :         if (f) {
     310         316 :                 append_modified_url(&ctx->val, &ctx->result, &ctx->url_app, PG(arg_separator).output);
     311             :         } else {
     312         214 :                 smart_str_append_smart_str(&ctx->result, &ctx->val);
     313             :         }
     314         530 :         if (quotes) {
     315         525 :                 smart_str_appendc(&ctx->result, type);
     316             :         }
     317         530 : }
     318             : 
     319             : enum {
     320             :         STATE_PLAIN = 0,
     321             :         STATE_TAG,
     322             :         STATE_NEXT_ARG,
     323             :         STATE_ARG,
     324             :         STATE_BEFORE_VAL,
     325             :         STATE_VAL
     326             : };
     327             : 
     328             : #define YYFILL(n) goto stop
     329             : #define YYCTYPE unsigned char
     330             : #define YYCURSOR xp
     331             : #define YYLIMIT end
     332             : #define YYMARKER q
     333             : #define STATE ctx->state
     334             : 
     335             : #define STD_PARA url_adapt_state_ex_t *ctx, char *start, char *YYCURSOR
     336             : #define STD_ARGS ctx, start, xp
     337             : 
     338             : #if SCANNER_DEBUG
     339             : #define scdebug(x) printf x
     340             : #else
     341             : #define scdebug(x)
     342             : #endif
     343             : 
     344        4794 : static inline void passthru(STD_PARA)
     345             : {
     346             :         scdebug(("appending %d chars, starting with %c\n", YYCURSOR-start, *start));
     347        4794 :         smart_str_appendl(&ctx->result, start, YYCURSOR - start);
     348        4794 : }
     349             : 
     350             : 
     351          16 : static int check_http_host(char *target)
     352             : {
     353             :         zval *host, *tmp;
     354             :         zend_string *host_tmp;
     355             :         char *colon;
     356             : 
     357          32 :         if ((tmp  = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_SERVER"))) &&
     358          31 :                 Z_TYPE_P(tmp) == IS_ARRAY &&
     359          27 :                 (host = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("HTTP_HOST"))) &&
     360          12 :                 Z_TYPE_P(host) == IS_STRING) {
     361          24 :                 host_tmp = zend_string_init(Z_STRVAL_P(host), Z_STRLEN_P(host), 0);
     362             :                 /* HTTP_HOST could be 'localhost:8888' etc. */
     363          12 :                 colon = strchr(ZSTR_VAL(host_tmp), ':');
     364          12 :                 if (colon) {
     365           0 :                         ZSTR_LEN(host_tmp) = colon - ZSTR_VAL(host_tmp);
     366           0 :                         ZSTR_VAL(host_tmp)[ZSTR_LEN(host_tmp)] = '\0';
     367             :                 }
     368          12 :                 if (!strcasecmp(ZSTR_VAL(host_tmp), target)) {
     369             :                         zend_string_release(host_tmp);
     370           4 :                         return SUCCESS;
     371             :                 }
     372             :                 zend_string_release(host_tmp);
     373             :         }
     374          12 :         return FAILURE;
     375             : }
     376             : 
     377         116 : static int check_host_whitelist(url_adapt_state_ex_t *ctx)
     378             : {
     379         116 :         php_url *url_parts = NULL;
     380         116 :         HashTable *allowed_hosts = ctx->type ? &BG(url_adapt_session_hosts_ht) : &BG(url_adapt_output_hosts_ht);
     381             : 
     382         116 :         ZEND_ASSERT(ctx->tag_type == TAG_FORM);
     383             : 
     384         116 :         if (ctx->attr_val.s && ZSTR_LEN(ctx->attr_val.s)) {
     385         106 :                 url_parts = php_url_parse_ex(ZSTR_VAL(ctx->attr_val.s), ZSTR_LEN(ctx->attr_val.s));
     386             :         } else {
     387          10 :                 return SUCCESS; /* empty URL is valid */
     388             :         }
     389             : 
     390         106 :         if (!url_parts) {
     391           0 :                 return FAILURE;
     392             :         }
     393         106 :         if (url_parts->scheme) {
     394             :                 /* Only http/https should be handled.
     395             :                    A bit hacky check this here, but saves a URL parse. */
     396          58 :                 if (strcasecmp(url_parts->scheme, "http") &&
     397          20 :                         strcasecmp(url_parts->scheme, "https")) {
     398          14 :                 php_url_free(url_parts);
     399          14 :                 return FAILURE;
     400             :                 }
     401             :         }
     402          92 :         if (!url_parts->host) {
     403          26 :                 php_url_free(url_parts);
     404          26 :                 return SUCCESS;
     405             :         }
     406          82 :         if (!zend_hash_num_elements(allowed_hosts) &&
     407          16 :                 check_http_host(url_parts->host) == SUCCESS) {
     408           4 :                 php_url_free(url_parts);
     409           4 :                 return SUCCESS;
     410             :         }
     411         124 :         if (!zend_hash_str_find(allowed_hosts,
     412          62 :                                                         url_parts->host,
     413          62 :                                                         strlen(url_parts->host))) {
     414          37 :                 php_url_free(url_parts);
     415          37 :                 return FAILURE;
     416             :         }
     417          25 :         php_url_free(url_parts);
     418          25 :         return SUCCESS;
     419             : }
     420             : 
     421             : /*
     422             :  * This function appends a hidden input field after a <form>.
     423             :  */
     424         432 : static void handle_form(STD_PARA)
     425             : {
     426         432 :         int doit = 0;
     427             : 
     428         432 :         if (ZSTR_LEN(ctx->form_app.s) > 0) {
     429         432 :                 switch (ZSTR_LEN(ctx->tag.s)) {
     430         116 :                         case sizeof("form") - 1:
     431         116 :                                 if (!strncasecmp(ZSTR_VAL(ctx->tag.s), "form", ZSTR_LEN(ctx->tag.s))
     432         116 :                                         && check_host_whitelist(ctx) == SUCCESS) {
     433          65 :                                         doit = 1;
     434             :                                 }
     435         116 :                                 break;
     436             :                 }
     437             :         }
     438             : 
     439         432 :         if (doit) {
     440          65 :                 smart_str_append_smart_str(&ctx->result, &ctx->form_app);
     441             :         }
     442         432 : }
     443             : 
     444             : /*
     445             :  *  HANDLE_TAG copies the HTML Tag and checks whether we
     446             :  *  have that tag in our table. If we might modify it,
     447             :  *  we continue to scan the tag, otherwise we simply copy the complete
     448             :  *  HTML stuff to the result buffer.
     449             :  */
     450             : 
     451         499 : static inline void handle_tag(STD_PARA)
     452             : {
     453         499 :         int ok = 0;
     454             :         unsigned int i;
     455             : 
     456         499 :         if (ctx->tag.s) {
     457         476 :                 ZSTR_LEN(ctx->tag.s) = 0;
     458             :         }
     459         499 :         smart_str_appendl(&ctx->tag, start, YYCURSOR - start);
     460        1600 :         for (i = 0; i < ZSTR_LEN(ctx->tag.s); i++)
     461        1101 :                 ZSTR_VAL(ctx->tag.s)[i] = tolower((int)(unsigned char)ZSTR_VAL(ctx->tag.s)[i]);
     462             :     /* intentionally using str_find here, in case the hash value is set, but the string val is changed later */
     463         998 :         if ((ctx->lookup_data = zend_hash_str_find_ptr(ctx->tags, ZSTR_VAL(ctx->tag.s), ZSTR_LEN(ctx->tag.s))) != NULL) {
     464         432 :                 ok = 1;
     465         432 :                 if (ZSTR_LEN(ctx->tag.s) == sizeof("form")-1
     466         116 :                         && !strncasecmp(ZSTR_VAL(ctx->tag.s), "form", ZSTR_LEN(ctx->tag.s))) {
     467         116 :                         ctx->tag_type = TAG_FORM;
     468             :                 } else {
     469         316 :                         ctx->tag_type = TAG_NORMAL;
     470             :                 }
     471             :         }
     472         499 :         STATE = ok ? STATE_NEXT_ARG : STATE_PLAIN;
     473         499 : }
     474             : 
     475         530 : static inline void handle_arg(STD_PARA)
     476             : {
     477         530 :         if (ctx->arg.s) {
     478         507 :                 ZSTR_LEN(ctx->arg.s) = 0;
     479             :         }
     480         530 :         smart_str_appendl(&ctx->arg, start, YYCURSOR - start);
     481         742 :         if (ctx->tag_type == TAG_FORM &&
     482         212 :                 strncasecmp(ZSTR_VAL(ctx->arg.s), "action", ZSTR_LEN(ctx->arg.s)) == 0) {
     483         102 :                 ctx->attr_type = ATTR_ACTION;
     484             :         } else {
     485         428 :                 ctx->attr_type = ATTR_NORMAL;
     486             :         }
     487         530 : }
     488             : 
     489         530 : static inline void handle_val(STD_PARA, char quotes, char type)
     490             : {
     491         530 :         smart_str_setl(&ctx->val, start + quotes, YYCURSOR - start - quotes * 2);
     492         530 :         if (ctx->tag_type == TAG_FORM && ctx->attr_type == ATTR_ACTION) {
     493         102 :                 smart_str_setl(&ctx->attr_val, start + quotes, YYCURSOR - start - quotes * 2);
     494             :         }
     495         530 :         tag_arg(ctx, quotes, type);
     496         530 : }
     497             : 
     498          28 : static inline void xx_mainloop(url_adapt_state_ex_t *ctx, const char *newdata, size_t newlen)
     499             : {
     500             :         char *end, *q;
     501             :         char *xp;
     502             :         char *start;
     503             :         size_t rest;
     504             : 
     505          28 :         smart_str_appendl(&ctx->buf, newdata, newlen);
     506             : 
     507          28 :         YYCURSOR = ZSTR_VAL(ctx->buf.s);
     508          28 :         YYLIMIT = ZSTR_VAL(ctx->buf.s) + ZSTR_LEN(ctx->buf.s);
     509             : 
     510          28 :         switch (STATE) {
     511          28 :                 case STATE_PLAIN: goto state_plain;
     512           0 :                 case STATE_TAG: goto state_tag;
     513           0 :                 case STATE_NEXT_ARG: goto state_next_arg;
     514           0 :                 case STATE_ARG: goto state_arg;
     515           0 :                 case STATE_BEFORE_VAL: goto state_before_val;
     516           0 :                 case STATE_VAL: goto state_val;
     517             :         }
     518             : 
     519             : 
     520         865 : state_plain_begin:
     521         865 :         STATE = STATE_PLAIN;
     522             : 
     523         960 : state_plain:
     524        1866 :         start = YYCURSOR;
     525             : /*!re2c
     526         932 :   "<"                              { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }
     527         906 :   N+                            { passthru(STD_ARGS); goto state_plain; }
     528             : */
     529             : 
     530         932 : state_tag:
     531         932 :         start = YYCURSOR;
     532             : /*!re2c
     533         499 :   alphanamespace+       { handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; }
     534         433 :   any           { passthru(STD_ARGS); goto state_plain_begin; }
     535             : */
     536             : 
     537         530 : state_next_arg_begin:
     538         530 :         STATE = STATE_NEXT_ARG;
     539             : 
     540         962 : state_next_arg:
     541        1494 :         start = YYCURSOR;
     542             : /*!re2c
     543         432 :   [/]? [>]           { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
     544         532 :   [ \v\r\t\n]+  { passthru(STD_ARGS); goto state_next_arg; }
     545         530 :   alpha         { --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
     546           0 :   any           { passthru(STD_ARGS); goto state_plain_begin; }
     547             : */
     548             : 
     549         530 : state_arg:
     550         530 :         start = YYCURSOR;
     551             : /*!re2c
     552         530 :   alpha alphadash*      { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
     553           0 :   any           { passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
     554             : */
     555             : 
     556         530 : state_before_val:
     557         530 :         start = YYCURSOR;
     558             : /*!re2c
     559         530 :   [ ]* "=" [ ]*               { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
     560           0 :   any                           { --YYCURSOR; goto state_next_arg_begin; }
     561             : */
     562             : 
     563             : 
     564         530 : state_val:
     565         530 :         start = YYCURSOR;
     566             : /*!re2c
     567         522 :   ["] (any\[">])* ["] { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
     568           3 :   ['] (any\['>])* [']        { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
     569           5 :   (any\[ \r\t\n>'"])+   { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
     570           0 :   any                                   { passthru(STD_ARGS); goto state_next_arg_begin; }
     571             : */
     572             : 
     573          28 : stop:
     574          28 :         if (YYLIMIT < start) {
     575             :                 /* XXX: Crash avoidance. Need to work with reporter to figure out what goes wrong */
     576           0 :                 rest = 0;
     577             :         } else {
     578          28 :                 rest = YYLIMIT - start;
     579             :                 scdebug(("stopped in state %d at pos %d (%d:%c) %d\n", STATE, YYCURSOR - ctx->buf.c, *YYCURSOR, *YYCURSOR, rest));
     580             :         }
     581             : 
     582          28 :         if (rest) memmove(ZSTR_VAL(ctx->buf.s), start, rest);
     583          28 :         ZSTR_LEN(ctx->buf.s) = rest;
     584          28 : }
     585             : 
     586             : 
     587           0 : 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)
     588             : {
     589             :         char *result;
     590           0 :         smart_str surl = {0};
     591           0 :         smart_str buf = {0};
     592           0 :         smart_str url_app = {0};
     593             :         zend_string *encoded;
     594             : 
     595             :         smart_str_appendl(&surl, url, urllen);
     596             : 
     597           0 :         if (encode) {
     598           0 :                 encoded = php_raw_url_encode(name, strlen(name));
     599           0 :                 smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
     600             :                 zend_string_free(encoded);
     601             :         } else {
     602           0 :                 smart_str_appends(&url_app, name);
     603             :         }
     604             :         smart_str_appendc(&url_app, '=');
     605           0 :         if (encode) {
     606           0 :                 encoded = php_raw_url_encode(value, strlen(value));
     607           0 :                 smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
     608             :                 zend_string_free(encoded);
     609             :         } else {
     610           0 :                 smart_str_appends(&url_app, value);
     611             :         }
     612             : 
     613           0 :         append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output);
     614             : 
     615             :         smart_str_0(&buf);
     616           0 :         if (newlen) *newlen = ZSTR_LEN(buf.s);
     617           0 :         result = estrndup(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s));
     618             : 
     619             :         smart_str_free(&url_app);
     620             :         smart_str_free(&buf);
     621             : 
     622           0 :         return result;
     623             : }
     624             : 
     625             : 
     626          28 : static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_bool do_flush, url_adapt_state_ex_t *ctx)
     627             : {
     628             :         char *retval;
     629             : 
     630          28 :         xx_mainloop(ctx, src, srclen);
     631             : 
     632          28 :         if (!ctx->result.s) {
     633           2 :                 smart_str_appendl(&ctx->result, "", 0);
     634           2 :                 *newlen = 0;
     635             :         } else {
     636          26 :                 *newlen = ZSTR_LEN(ctx->result.s);
     637             :         }
     638          28 :         smart_str_0(&ctx->result);
     639          28 :         if (do_flush) {
     640          28 :                 smart_str_append(&ctx->result, ctx->buf.s);
     641          28 :                 *newlen += ZSTR_LEN(ctx->buf.s);
     642          28 :                 smart_str_free(&ctx->buf);
     643          28 :                 smart_str_free(&ctx->val);
     644          28 :                 smart_str_free(&ctx->attr_val);
     645             :         }
     646          28 :         retval = estrndup(ZSTR_VAL(ctx->result.s), ZSTR_LEN(ctx->result.s));
     647          28 :         smart_str_free(&ctx->result);
     648          28 :         return retval;
     649             : }
     650             : 
     651          23 : static int php_url_scanner_ex_activate(int type)
     652             : {
     653             :         url_adapt_state_ex_t *ctx;
     654             : 
     655          23 :         if (type) {
     656          14 :                 ctx = &BG(url_adapt_session_ex);
     657             :         } else {
     658           9 :                 ctx = &BG(url_adapt_output_ex);
     659             :         }
     660             : 
     661          23 :         memset(ctx, 0, ((size_t) &((url_adapt_state_ex_t *)0)->tags));
     662             : 
     663          23 :         return SUCCESS;
     664             : }
     665             : 
     666          23 : static int php_url_scanner_ex_deactivate(int type)
     667             : {
     668             :         url_adapt_state_ex_t *ctx;
     669             : 
     670          23 :         if (type) {
     671          14 :                 ctx = &BG(url_adapt_session_ex);
     672             :         } else {
     673           9 :                 ctx = &BG(url_adapt_output_ex);
     674             :         }
     675             : 
     676          23 :         smart_str_free(&ctx->result);
     677          23 :         smart_str_free(&ctx->buf);
     678          23 :         smart_str_free(&ctx->tag);
     679          23 :         smart_str_free(&ctx->arg);
     680          23 :         smart_str_free(&ctx->attr_val);
     681             : 
     682          23 :         return SUCCESS;
     683             : }
     684             : 
     685          29 : static inline void php_url_scanner_session_handler_impl(char *output, size_t output_len, char **handled_output, size_t *handled_output_len, int mode, int type)
     686             : {
     687             :         size_t len;
     688             :         url_adapt_state_ex_t *url_state;
     689             : 
     690          29 :         if (type) {
     691          17 :                 url_state = &BG(url_adapt_session_ex);
     692             :         } else {
     693          12 :                 url_state = &BG(url_adapt_output_ex);
     694             :         }
     695             : 
     696          29 :         if (ZSTR_LEN(url_state->url_app.s) != 0) {
     697          28 :                 *handled_output = url_adapt_ext(output, output_len, &len, (zend_bool) (mode & (PHP_OUTPUT_HANDLER_END | PHP_OUTPUT_HANDLER_CONT | PHP_OUTPUT_HANDLER_FLUSH | PHP_OUTPUT_HANDLER_FINAL) ? 1 : 0), url_state);
     698             :                 if (sizeof(uint) < sizeof(size_t)) {
     699          28 :                         if (len > UINT_MAX)
     700           0 :                                 len = UINT_MAX;
     701             :                 }
     702          28 :                 *handled_output_len = len;
     703           1 :         } else if (ZSTR_LEN(url_state->url_app.s) == 0) {
     704           1 :                 url_adapt_state_ex_t *ctx = url_state;
     705           1 :                 if (ctx->buf.s && ZSTR_LEN(ctx->buf.s)) {
     706           0 :                         smart_str_append(&ctx->result, ctx->buf.s);
     707           0 :                         smart_str_appendl(&ctx->result, output, output_len);
     708             : 
     709           0 :                         *handled_output = estrndup(ZSTR_VAL(ctx->result.s), ZSTR_LEN(ctx->result.s));
     710           0 :                         *handled_output_len = ZSTR_LEN(ctx->buf.s) + output_len;
     711             : 
     712           0 :                         smart_str_free(&ctx->buf);
     713           0 :                         smart_str_free(&ctx->result);
     714             :                 } else {
     715           1 :                         *handled_output = estrndup(output, *handled_output_len = output_len);
     716             :                 }
     717             :         } else {
     718           0 :                 *handled_output = NULL;
     719             :         }
     720          29 : }
     721             : 
     722          17 : static void php_url_scanner_session_handler(char *output, size_t output_len, char **handled_output, size_t *handled_output_len, int mode)
     723             : {
     724          17 :         php_url_scanner_session_handler_impl(output, output_len, handled_output, handled_output_len, mode, 1);
     725          17 : }
     726             : 
     727          12 : static void php_url_scanner_output_handler(char *output, size_t output_len, char **handled_output, size_t *handled_output_len, int mode)
     728             : {
     729          12 :         php_url_scanner_session_handler_impl(output, output_len, handled_output, handled_output_len, mode, 0);
     730          12 : }
     731             : 
     732          35 : 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)
     733             : {
     734          35 :         smart_str sname = {0};
     735          35 :         smart_str svalue = {0};
     736          35 :         smart_str hname = {0};
     737          35 :         smart_str hvalue = {0};
     738             :         zend_string *encoded;
     739             :         url_adapt_state_ex_t *url_state;
     740             :         php_output_handler_func_t handler;
     741             : 
     742          35 :         if (type) {
     743          17 :                 url_state = &BG(url_adapt_session_ex);
     744          17 :                 handler = php_url_scanner_session_handler;
     745             :         } else {
     746          18 :                 url_state = &BG(url_adapt_output_ex);
     747          18 :                 handler = php_url_scanner_output_handler;
     748             :         }
     749             : 
     750          35 :         if (!url_state->active) {
     751          23 :                 php_url_scanner_ex_activate(type);
     752          23 :                 php_output_start_internal(ZEND_STRL("URL-Rewriter"), handler, 0, PHP_OUTPUT_HANDLER_STDFLAGS);
     753          23 :                 url_state->active = 1;
     754             :         }
     755             : 
     756          35 :         if (url_state->url_app.s && ZSTR_LEN(url_state->url_app.s) != 0) {
     757           5 :                 smart_str_appends(&url_state->url_app, PG(arg_separator).output);
     758             :         }
     759             : 
     760          35 :         if (encode) {
     761          35 :                 encoded = php_raw_url_encode(name, name_len);
     762          35 :                 smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded);
     763          35 :                 encoded = php_raw_url_encode(value, value_len);
     764          35 :                 smart_str_appendl(&svalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded);
     765          35 :                 encoded = php_escape_html_entities_ex((unsigned char*)name, name_len, 0, ENT_QUOTES|ENT_SUBSTITUTE, SG(default_charset), 0);
     766          35 :                 smart_str_appendl(&hname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded);
     767          35 :                 encoded = php_escape_html_entities_ex((unsigned char*)value, value_len, 0, ENT_QUOTES|ENT_SUBSTITUTE, SG(default_charset), 0);
     768          35 :                 smart_str_appendl(&hvalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded);
     769             :         } else {
     770             :                 smart_str_appendl(&sname, name, name_len);
     771             :                 smart_str_appendl(&svalue, value, value_len);
     772             :                 smart_str_appendl(&hname, name, name_len);
     773             :                 smart_str_appendl(&hvalue, value, value_len);
     774             :         }
     775             : 
     776          35 :         smart_str_append_smart_str(&url_state->url_app, &sname);
     777          35 :         smart_str_appendc(&url_state->url_app, '=');
     778          35 :         smart_str_append_smart_str(&url_state->url_app, &svalue);
     779             : 
     780          35 :         smart_str_appends(&url_state->form_app, "<input type=\"hidden\" name=\"");
     781          35 :         smart_str_append_smart_str(&url_state->form_app, &hname);
     782          35 :         smart_str_appends(&url_state->form_app, "\" value=\"");
     783          35 :         smart_str_append_smart_str(&url_state->form_app, &hvalue);
     784          35 :         smart_str_appends(&url_state->form_app, "\" />");
     785             : 
     786             :         smart_str_free(&sname);
     787             :         smart_str_free(&svalue);
     788             :         smart_str_free(&hname);
     789             :         smart_str_free(&hvalue);
     790             : 
     791          35 :         return SUCCESS;
     792             : }
     793             : 
     794             : 
     795          17 : PHPAPI int php_url_scanner_add_session_var(char *name, size_t name_len, char *value, size_t value_len, int encode)
     796             : {
     797          17 :         return php_url_scanner_add_var_impl(name, name_len, value, value_len, encode, 1);
     798             : }
     799             : 
     800             : 
     801          18 : PHPAPI int php_url_scanner_add_var(char *name, size_t name_len, char *value, size_t value_len, int encode)
     802             : {
     803          18 :         return php_url_scanner_add_var_impl(name, name_len, value, value_len, encode, 0);
     804             : }
     805             : 
     806             : 
     807           8 : static inline void php_url_scanner_reset_vars_impl(int type) {
     808             :         url_adapt_state_ex_t *url_state;
     809             : 
     810           8 :         if (type) {
     811           3 :                 url_state = &BG(url_adapt_session_ex);
     812             :         } else {
     813           5 :                 url_state = &BG(url_adapt_output_ex);
     814             :         }
     815             : 
     816           8 :         if (url_state->form_app.s) {
     817           8 :                 ZSTR_LEN(url_state->form_app.s) = 0;
     818             :         }
     819           8 :         if (url_state->url_app.s) {
     820           8 :                 ZSTR_LEN(url_state->url_app.s) = 0;
     821             :         }
     822           8 : }
     823             : 
     824             : 
     825           0 : PHPAPI int php_url_scanner_reset_session_vars(void)
     826             : {
     827           0 :         php_url_scanner_reset_vars_impl(1);
     828           0 :         return SUCCESS;
     829             : }
     830             : 
     831             : 
     832           5 : PHPAPI int php_url_scanner_reset_vars(void)
     833             : {
     834           5 :         php_url_scanner_reset_vars_impl(0);
     835           5 :         return SUCCESS;
     836             : }
     837             : 
     838             : 
     839          17 : static inline int php_url_scanner_reset_var_impl(zend_string *name, int encode, int type)
     840             : {
     841             :         char *start, *end, *limit;
     842             :         size_t separator_len;
     843          17 :         smart_str sname = {0};
     844          17 :         smart_str hname = {0};
     845          17 :         smart_str url_app = {0};
     846          17 :         smart_str form_app = {0};
     847             :         zend_string *encoded;
     848          17 :         int ret = SUCCESS;
     849          17 :         zend_bool sep_removed = 0;
     850             :         url_adapt_state_ex_t *url_state;
     851             : 
     852          17 :         if (type) {
     853          17 :                 url_state = &BG(url_adapt_session_ex);
     854             :         } else {
     855           0 :                 url_state = &BG(url_adapt_output_ex);
     856             :         }
     857             : 
     858             :         /* Short circuit check. Only check url_app. */
     859          17 :         if (!url_state->url_app.s || !ZSTR_LEN(url_state->url_app.s)) {
     860          14 :                 return SUCCESS;
     861             :         }
     862             : 
     863           3 :         if (encode) {
     864           3 :                 encoded = php_raw_url_encode(ZSTR_VAL(name), ZSTR_LEN(name));
     865           3 :                 smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
     866             :                 zend_string_free(encoded);
     867           3 :                 encoded = php_escape_html_entities_ex((unsigned char *)ZSTR_VAL(name), ZSTR_LEN(name), 0, ENT_QUOTES|ENT_SUBSTITUTE, SG(default_charset), 0);
     868           3 :                 smart_str_appendl(&hname, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
     869             :                 zend_string_free(encoded);
     870             :         } else {
     871           0 :                 smart_str_appendl(&sname, ZSTR_VAL(name), ZSTR_LEN(name));
     872           0 :                 smart_str_appendl(&hname, ZSTR_VAL(name), ZSTR_LEN(name));
     873             :         }
     874             :         smart_str_0(&sname);
     875             :         smart_str_0(&hname);
     876             : 
     877             :         smart_str_append_smart_str(&url_app, &sname);
     878             :         smart_str_appendc(&url_app, '=');
     879             :         smart_str_0(&url_app);
     880             : 
     881             :         smart_str_appends(&form_app, "<input type=\"hidden\" name=\"");
     882             :         smart_str_append_smart_str(&form_app, &hname);
     883             :         smart_str_appends(&form_app, "\" value=\"");
     884             :         smart_str_0(&form_app);
     885             : 
     886             :         /* Short circuit check. Only check url_app. */
     887          12 :         start = (char *) php_memnstr(ZSTR_VAL(url_state->url_app.s),
     888           6 :                                                                  ZSTR_VAL(url_app.s), ZSTR_LEN(url_app.s),
     889           3 :                                                                  ZSTR_VAL(url_state->url_app.s) + ZSTR_LEN(url_state->url_app.s));
     890           3 :         if (!start) {
     891           0 :                 ret = FAILURE;
     892           0 :                 goto finish;
     893             :         }
     894             : 
     895             :         /* Get end of url var */
     896           3 :         limit = ZSTR_VAL(url_state->url_app.s) + ZSTR_LEN(url_state->url_app.s);
     897           3 :         end = start + ZSTR_LEN(url_app.s);
     898           3 :         separator_len = strlen(PG(arg_separator).output);
     899          23 :         while (end < limit) {
     900          17 :                 if (!memcmp(end, PG(arg_separator).output, separator_len)) {
     901           0 :                         end += separator_len;
     902           0 :                         sep_removed = 1;
     903           0 :                         break;
     904             :                 }
     905          17 :                 end++;
     906             :         }
     907             :         /* Remove all when this is the only rewrite var */
     908           3 :         if (ZSTR_LEN(url_state->url_app.s) == end - start) {
     909           3 :                 php_url_scanner_reset_vars_impl(type);
     910           3 :                 goto finish;
     911             :         }
     912             :         /* Check preceeding separator */
     913           0 :         if (!sep_removed
     914           0 :                 && start - PG(arg_separator).output >= separator_len
     915           0 :                 && !memcmp(start - separator_len, PG(arg_separator).output, separator_len)) {
     916           0 :                 start -= separator_len;
     917             :         }
     918             :         /* Remove partially */
     919           0 :         memmove(start, end,
     920           0 :                         ZSTR_LEN(url_state->url_app.s) - (end - ZSTR_VAL(url_state->url_app.s)));
     921           0 :         ZSTR_LEN(url_state->url_app.s) -= end - start;
     922           0 :         ZSTR_VAL(url_state->url_app.s)[ZSTR_LEN(url_state->url_app.s)] = '\0';
     923             : 
     924             :         /* Remove form var */
     925           0 :         start = (char *) php_memnstr(ZSTR_VAL(url_state->form_app.s),
     926           0 :                                                 ZSTR_VAL(form_app.s), ZSTR_LEN(form_app.s),
     927           0 :                                                 ZSTR_VAL(url_state->form_app.s) + ZSTR_LEN(url_state->form_app.s));
     928           0 :         if (!start) {
     929             :                 /* Should not happen */
     930           0 :                 ret = FAILURE;
     931           0 :                 php_url_scanner_reset_vars_impl(type);
     932           0 :                 goto finish;
     933             :         }
     934             :         /* Get end of form var */
     935           0 :         limit = ZSTR_VAL(url_state->form_app.s) + ZSTR_LEN(url_state->form_app.s);
     936           0 :         end = start + ZSTR_LEN(form_app.s);
     937           0 :         while (end < limit) {
     938           0 :                 if (*end == '>') {
     939           0 :                         end += 1;
     940           0 :                         break;
     941             :                 }
     942           0 :                 end++;
     943             :         }
     944             :         /* Remove partially */
     945           0 :         memmove(start, end,
     946           0 :                         ZSTR_LEN(url_state->form_app.s) - (end - ZSTR_VAL(url_state->form_app.s)));
     947           0 :         ZSTR_LEN(url_state->form_app.s) -= end - start;
     948           0 :         ZSTR_VAL(url_state->form_app.s)[ZSTR_LEN(url_state->form_app.s)] = '\0';
     949             : 
     950           3 : finish:
     951             :         smart_str_free(&url_app);
     952             :         smart_str_free(&form_app);
     953             :         smart_str_free(&sname);
     954             :         smart_str_free(&hname);
     955           3 :         return ret;
     956             : }
     957             : 
     958             : 
     959          17 : PHPAPI int php_url_scanner_reset_session_var(zend_string *name, int encode)
     960             : {
     961          17 :         return php_url_scanner_reset_var_impl(name, encode, 1);
     962             : }
     963             : 
     964             : 
     965           0 : PHPAPI int php_url_scanner_reset_var(zend_string *name, int encode)
     966             : {
     967           0 :         return php_url_scanner_reset_var_impl(name, encode, 0);
     968             : }
     969             : 
     970             : 
     971       24801 : PHP_MINIT_FUNCTION(url_scanner)
     972             : {
     973       24801 :         REGISTER_INI_ENTRIES();
     974       24801 :         return SUCCESS;
     975             : }
     976             : 
     977       24843 : PHP_MSHUTDOWN_FUNCTION(url_scanner)
     978             : {
     979       24843 :         UNREGISTER_INI_ENTRIES();
     980             : 
     981       24843 :         return SUCCESS;
     982             : }
     983             : 
     984       24751 : PHP_RINIT_FUNCTION(url_scanner)
     985             : {
     986       24751 :         BG(url_adapt_session_ex).active    = 0;
     987       24751 :         BG(url_adapt_session_ex).tag_type  = 0;
     988       24751 :         BG(url_adapt_session_ex).attr_type = 0;
     989       24751 :         BG(url_adapt_output_ex).active    = 0;
     990       24751 :         BG(url_adapt_output_ex).tag_type  = 0;
     991       24751 :         BG(url_adapt_output_ex).attr_type = 0;
     992       24751 :         return SUCCESS;
     993             : }
     994             : 
     995       24797 : PHP_RSHUTDOWN_FUNCTION(url_scanner)
     996             : {
     997       24797 :         if (BG(url_adapt_session_ex).active) {
     998          14 :                 php_url_scanner_ex_deactivate(1);
     999          14 :                 BG(url_adapt_session_ex).active    = 0;
    1000          14 :                 BG(url_adapt_session_ex).tag_type  = 0;
    1001          14 :                 BG(url_adapt_session_ex).attr_type = 0;
    1002             :         }
    1003             :         smart_str_free(&BG(url_adapt_session_ex).form_app);
    1004             :         smart_str_free(&BG(url_adapt_session_ex).url_app);
    1005             : 
    1006       24797 :         if (BG(url_adapt_output_ex).active) {
    1007           9 :                 php_url_scanner_ex_deactivate(0);
    1008           9 :                 BG(url_adapt_output_ex).active    = 0;
    1009           9 :                 BG(url_adapt_output_ex).tag_type  = 0;
    1010           9 :                 BG(url_adapt_output_ex).attr_type = 0;
    1011             :         }
    1012             :         smart_str_free(&BG(url_adapt_output_ex).form_app);
    1013             :         smart_str_free(&BG(url_adapt_output_ex).url_app);
    1014             : 
    1015       24797 :         return SUCCESS;
    1016             : }

Generated by: LCOV version 1.10

Generated at Sun, 16 Jan 2022 08:19:26 +0000 (6 days ago)

Copyright © 2005-2022 The PHP Group
All rights reserved.