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

Generated by: LCOV version 1.10

Generated at Tue, 27 Sep 2016 10:26:11 +0000 (1 minute ago)

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