root/ext/standard/url_scanner_ex.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tag_dtor
  2. PHP_INI_MH
  3. append_modified_url
  4. tag_arg
  5. passthru
  6. handle_form
  7. handle_tag
  8. handle_arg
  9. handle_val
  10. xx_mainloop
  11. php_url_scanner_adapt_single_url
  12. url_adapt_ext
  13. php_url_scanner_ex_activate
  14. php_url_scanner_ex_deactivate
  15. php_url_scanner_output_handler
  16. php_url_scanner_add_var
  17. php_url_scanner_reset_vars
  18. PHP_MINIT_FUNCTION
  19. PHP_MSHUTDOWN_FUNCTION
  20. PHP_RINIT_FUNCTION
  21. PHP_RSHUTDOWN_FUNCTION

   1 /* Generated by re2c 0.13.5 */
   2 /*
   3   +----------------------------------------------------------------------+
   4   | PHP Version 7                                                        |
   5   +----------------------------------------------------------------------+
   6   | Copyright (c) 1997-2016 The PHP Group                                |
   7   +----------------------------------------------------------------------+
   8   | This source file is subject to version 3.01 of the PHP license,      |
   9   | that is bundled with this package in the file LICENSE, and is        |
  10   | available through the world-wide-web at the following url:           |
  11   | http://www.php.net/license/3_01.txt                                  |
  12   | If you did not receive a copy of the PHP license and are unable to   |
  13   | obtain it through the world-wide-web, please send a note to          |
  14   | license@php.net so we can mail you a copy immediately.               |
  15   +----------------------------------------------------------------------+
  16   | Author: Sascha Schumann <sascha@schumann.cx>                         |
  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 "php_ini.h"
  36 #include "php_globals.h"
  37 #define STATE_TAG SOME_OTHER_STATE_TAG
  38 #include "basic_functions.h"
  39 #include "url.h"
  40 #undef STATE_TAG
  41 
  42 #define url_scanner url_scanner_ex
  43 
  44 #include "zend_smart_str.h"
  45 
  46 static void tag_dtor(zval *zv)
  47 {
  48         free(Z_PTR_P(zv));
  49 }
  50 
  51 static PHP_INI_MH(OnUpdateTags)
  52 {
  53         url_adapt_state_ex_t *ctx;
  54         char *key;
  55         char *tmp;
  56         char *lasts = NULL;
  57 
  58         ctx = &BG(url_adapt_state_ex);
  59 
  60         tmp = estrndup(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
  61 
  62         if (ctx->tags)
  63                 zend_hash_destroy(ctx->tags);
  64         else {
  65                 ctx->tags = malloc(sizeof(HashTable));
  66                 if (!ctx->tags) {
  67                         return FAILURE;
  68                 }
  69         }
  70 
  71         zend_hash_init(ctx->tags, 0, NULL, tag_dtor, 1);
  72 
  73         for (key = php_strtok_r(tmp, ",", &lasts);
  74                         key;
  75                         key = php_strtok_r(NULL, ",", &lasts)) {
  76                 char *val;
  77 
  78                 val = strchr(key, '=');
  79                 if (val) {
  80                         char *q;
  81                         size_t keylen;
  82 
  83                         *val++ = '\0';
  84                         for (q = key; *q; q++)
  85                                 *q = tolower(*q);
  86                         keylen = q - key;
  87                         /* key is stored withOUT NUL
  88                            val is stored WITH    NUL */
  89                         zend_hash_str_add_mem(ctx->tags, key, keylen, val, strlen(val)+1);
  90                 }
  91         }
  92 
  93         efree(tmp);
  94 
  95         return SUCCESS;
  96 }
  97 
  98 PHP_INI_BEGIN()
  99         STD_PHP_INI_ENTRY("url_rewriter.tags", "a=href,area=href,frame=src,form=,fieldset=", PHP_INI_ALL, OnUpdateTags, url_adapt_state_ex, php_basic_globals, basic_globals)
 100 PHP_INI_END()
 101 
 102 
 103 
 104 #define YYFILL(n) goto done
 105 #define YYCTYPE unsigned char
 106 #define YYCURSOR p
 107 #define YYLIMIT q
 108 #define YYMARKER r
 109 
 110 static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator)
 111 {
 112         register const char *p, *q;
 113         const char *bash = NULL;
 114         const char *sep = "?";
 115 
 116         q = (p = ZSTR_VAL(url->s)) + ZSTR_LEN(url->s);
 117 
 118 scan:
 119 
 120 {
 121         YYCTYPE yych;
 122         static const unsigned char yybm[] = {
 123                 128, 128, 128, 128, 128, 128, 128, 128, 
 124                 128, 128, 128, 128, 128, 128, 128, 128, 
 125                 128, 128, 128, 128, 128, 128, 128, 128, 
 126                 128, 128, 128, 128, 128, 128, 128, 128, 
 127                 128, 128, 128,   0, 128, 128, 128, 128, 
 128                 128, 128, 128, 128, 128, 128, 128, 128, 
 129                 128, 128, 128, 128, 128, 128, 128, 128, 
 130                 128, 128,   0, 128, 128, 128, 128,   0, 
 131                 128, 128, 128, 128, 128, 128, 128, 128, 
 132                 128, 128, 128, 128, 128, 128, 128, 128, 
 133                 128, 128, 128, 128, 128, 128, 128, 128, 
 134                 128, 128, 128, 128, 128, 128, 128, 128, 
 135                 128, 128, 128, 128, 128, 128, 128, 128, 
 136                 128, 128, 128, 128, 128, 128, 128, 128, 
 137                 128, 128, 128, 128, 128, 128, 128, 128, 
 138                 128, 128, 128, 128, 128, 128, 128, 128, 
 139                 128, 128, 128, 128, 128, 128, 128, 128, 
 140                 128, 128, 128, 128, 128, 128, 128, 128, 
 141                 128, 128, 128, 128, 128, 128, 128, 128, 
 142                 128, 128, 128, 128, 128, 128, 128, 128, 
 143                 128, 128, 128, 128, 128, 128, 128, 128, 
 144                 128, 128, 128, 128, 128, 128, 128, 128, 
 145                 128, 128, 128, 128, 128, 128, 128, 128, 
 146                 128, 128, 128, 128, 128, 128, 128, 128, 
 147                 128, 128, 128, 128, 128, 128, 128, 128, 
 148                 128, 128, 128, 128, 128, 128, 128, 128, 
 149                 128, 128, 128, 128, 128, 128, 128, 128, 
 150                 128, 128, 128, 128, 128, 128, 128, 128, 
 151                 128, 128, 128, 128, 128, 128, 128, 128, 
 152                 128, 128, 128, 128, 128, 128, 128, 128, 
 153                 128, 128, 128, 128, 128, 128, 128, 128, 
 154                 128, 128, 128, 128, 128, 128, 128, 128, 
 155         };
 156 
 157         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 158         yych = *YYCURSOR;
 159         if (yybm[0+yych] & 128) {
 160                 goto yy8;
 161         }
 162         if (yych <= '9') goto yy6;
 163         if (yych >= ';') goto yy4;
 164         ++YYCURSOR;
 165         { smart_str_append_smart_str(dest, url); return; }
 166 yy4:
 167         ++YYCURSOR;
 168         { sep = separator; goto scan; }
 169 yy6:
 170         ++YYCURSOR;
 171         { bash = p - 1; goto done; }
 172 yy8:
 173         ++YYCURSOR;
 174         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 175         yych = *YYCURSOR;
 176         if (yybm[0+yych] & 128) {
 177                 goto yy8;
 178         }
 179         { goto scan; }
 180 }
 181 
 182 done:
 183 
 184         /* Don't modify URLs of the format "#mark" */
 185         if (bash && bash - ZSTR_VAL(url->s) == 0) {
 186                 smart_str_append_smart_str(dest, url);
 187                 return;
 188         }
 189 
 190         if (bash)
 191                 smart_str_appendl(dest, ZSTR_VAL(url->s), bash - ZSTR_VAL(url->s));
 192         else
 193                 smart_str_append_smart_str(dest, url);
 194 
 195         smart_str_appends(dest, sep);
 196         smart_str_append_smart_str(dest, url_app);
 197 
 198         if (bash)
 199                 smart_str_appendl(dest, bash, q - bash);
 200 }
 201 
 202 
 203 #undef YYFILL
 204 #undef YYCTYPE
 205 #undef YYCURSOR
 206 #undef YYLIMIT
 207 #undef YYMARKER
 208 
 209 static inline void tag_arg(url_adapt_state_ex_t *ctx, char quotes, char type)
 210 {
 211         char f = 0;
 212 
 213         if (strncasecmp(ZSTR_VAL(ctx->arg.s), ctx->lookup_data, ZSTR_LEN(ctx->arg.s)) == 0)
 214                 f = 1;
 215 
 216         if (quotes)
 217                 smart_str_appendc(&ctx->result, type);
 218         if (f) {
 219                 append_modified_url(&ctx->val, &ctx->result, &ctx->url_app, PG(arg_separator).output);
 220         } else {
 221                 smart_str_append_smart_str(&ctx->result, &ctx->val);
 222         }
 223         if (quotes)
 224                 smart_str_appendc(&ctx->result, type);
 225 }
 226 
 227 enum {
 228         STATE_PLAIN = 0,
 229         STATE_TAG,
 230         STATE_NEXT_ARG,
 231         STATE_ARG,
 232         STATE_BEFORE_VAL,
 233         STATE_VAL
 234 };
 235 
 236 #define YYFILL(n) goto stop
 237 #define YYCTYPE unsigned char
 238 #define YYCURSOR xp
 239 #define YYLIMIT end
 240 #define YYMARKER q
 241 #define STATE ctx->state
 242 
 243 #define STD_PARA url_adapt_state_ex_t *ctx, char *start, char *YYCURSOR
 244 #define STD_ARGS ctx, start, xp
 245 
 246 #if SCANNER_DEBUG
 247 #define scdebug(x) printf x
 248 #else
 249 #define scdebug(x)
 250 #endif
 251 
 252 static inline void passthru(STD_PARA)
 253 {
 254         scdebug(("appending %d chars, starting with %c\n", YYCURSOR-start, *start));
 255         smart_str_appendl(&ctx->result, start, YYCURSOR - start);
 256 }
 257 
 258 /*
 259  * This function appends a hidden input field after a <form> or
 260  * <fieldset>.  The latter is important for XHTML.
 261  */
 262 
 263 static void handle_form(STD_PARA)
 264 {
 265         int doit = 0;
 266 
 267         if (ZSTR_LEN(ctx->form_app.s) > 0) {
 268                 switch (ZSTR_LEN(ctx->tag.s)) {
 269                         case sizeof("form") - 1:
 270                                 if (!strncasecmp(ZSTR_VAL(ctx->tag.s), "form", sizeof("form") - 1)) {
 271                                         doit = 1;
 272                                 }
 273                                 if (doit && ctx->val.s && ctx->lookup_data && *ctx->lookup_data) {
 274                                         char *e, *p = (char *)zend_memnstr(ZSTR_VAL(ctx->val.s), "://", sizeof("://") - 1, ZSTR_VAL(ctx->val.s) + ZSTR_LEN(ctx->val.s));
 275                                         if (p) {
 276                                                 e = memchr(p, '/', (ZSTR_VAL(ctx->val.s) + ZSTR_LEN(ctx->val.s)) - p);
 277                                                 if (!e) {
 278                                                         e = ZSTR_VAL(ctx->val.s) + ZSTR_LEN(ctx->val.s);
 279                                                 }
 280                                                 if ((e - p) && strncasecmp(p, ctx->lookup_data, (e - p))) {
 281                                                         doit = 0;
 282                                                 }
 283                                         }
 284                                 }
 285                                 break;
 286 
 287                         case sizeof("fieldset") - 1:
 288                                 if (!strncasecmp(ZSTR_VAL(ctx->tag.s), "fieldset", sizeof("fieldset") - 1)) {
 289                                         doit = 1;
 290                                 }
 291                                 break;
 292                 }
 293 
 294                 if (doit)
 295                         smart_str_append_smart_str(&ctx->result, &ctx->form_app);
 296         }
 297 }
 298 
 299 /*
 300  *  HANDLE_TAG copies the HTML Tag and checks whether we
 301  *  have that tag in our table. If we might modify it,
 302  *  we continue to scan the tag, otherwise we simply copy the complete
 303  *  HTML stuff to the result buffer.
 304  */
 305 
 306 static inline void handle_tag(STD_PARA)
 307 {
 308         int ok = 0;
 309         unsigned int i;
 310 
 311         if (ctx->tag.s) {
 312                 ZSTR_LEN(ctx->tag.s) = 0;
 313         }
 314         smart_str_appendl(&ctx->tag, start, YYCURSOR - start);
 315         for (i = 0; i < ZSTR_LEN(ctx->tag.s); i++)
 316                 ZSTR_VAL(ctx->tag.s)[i] = tolower((int)(unsigned char)ZSTR_VAL(ctx->tag.s)[i]);
 317     /* intentionally using str_find here, in case the hash value is set, but the string val is changed later */
 318         if ((ctx->lookup_data = zend_hash_str_find_ptr(ctx->tags, ZSTR_VAL(ctx->tag.s), ZSTR_LEN(ctx->tag.s))) != NULL)
 319                 ok = 1;
 320         STATE = ok ? STATE_NEXT_ARG : STATE_PLAIN;
 321 }
 322 
 323 static inline void handle_arg(STD_PARA)
 324 {
 325         if (ctx->arg.s) {
 326                 ZSTR_LEN(ctx->arg.s) = 0;
 327         }
 328         smart_str_appendl(&ctx->arg, start, YYCURSOR - start);
 329 }
 330 
 331 static inline void handle_val(STD_PARA, char quotes, char type)
 332 {
 333         smart_str_setl(&ctx->val, start + quotes, YYCURSOR - start - quotes * 2);
 334         tag_arg(ctx, quotes, type);
 335 }
 336 
 337 static inline void xx_mainloop(url_adapt_state_ex_t *ctx, const char *newdata, size_t newlen)
 338 {
 339         char *end, *q;
 340         char *xp;
 341         char *start;
 342         size_t rest;
 343 
 344         smart_str_appendl(&ctx->buf, newdata, newlen);
 345 
 346         YYCURSOR = ZSTR_VAL(ctx->buf.s);
 347         YYLIMIT = ZSTR_VAL(ctx->buf.s) + ZSTR_LEN(ctx->buf.s);
 348 
 349         switch (STATE) {
 350                 case STATE_PLAIN: goto state_plain;
 351                 case STATE_TAG: goto state_tag;
 352                 case STATE_NEXT_ARG: goto state_next_arg;
 353                 case STATE_ARG: goto state_arg;
 354                 case STATE_BEFORE_VAL: goto state_before_val;
 355                 case STATE_VAL: goto state_val;
 356         }
 357 
 358 
 359 state_plain_begin:
 360         STATE = STATE_PLAIN;
 361 
 362 state_plain:
 363         start = YYCURSOR;
 364 
 365 {
 366         YYCTYPE yych;
 367         static const unsigned char yybm[] = {
 368                 128, 128, 128, 128, 128, 128, 128, 128, 
 369                 128, 128, 128, 128, 128, 128, 128, 128, 
 370                 128, 128, 128, 128, 128, 128, 128, 128, 
 371                 128, 128, 128, 128, 128, 128, 128, 128, 
 372                 128, 128, 128, 128, 128, 128, 128, 128, 
 373                 128, 128, 128, 128, 128, 128, 128, 128, 
 374                 128, 128, 128, 128, 128, 128, 128, 128, 
 375                 128, 128, 128, 128,   0, 128, 128, 128, 
 376                 128, 128, 128, 128, 128, 128, 128, 128, 
 377                 128, 128, 128, 128, 128, 128, 128, 128, 
 378                 128, 128, 128, 128, 128, 128, 128, 128, 
 379                 128, 128, 128, 128, 128, 128, 128, 128, 
 380                 128, 128, 128, 128, 128, 128, 128, 128, 
 381                 128, 128, 128, 128, 128, 128, 128, 128, 
 382                 128, 128, 128, 128, 128, 128, 128, 128, 
 383                 128, 128, 128, 128, 128, 128, 128, 128, 
 384                 128, 128, 128, 128, 128, 128, 128, 128, 
 385                 128, 128, 128, 128, 128, 128, 128, 128, 
 386                 128, 128, 128, 128, 128, 128, 128, 128, 
 387                 128, 128, 128, 128, 128, 128, 128, 128, 
 388                 128, 128, 128, 128, 128, 128, 128, 128, 
 389                 128, 128, 128, 128, 128, 128, 128, 128, 
 390                 128, 128, 128, 128, 128, 128, 128, 128, 
 391                 128, 128, 128, 128, 128, 128, 128, 128, 
 392                 128, 128, 128, 128, 128, 128, 128, 128, 
 393                 128, 128, 128, 128, 128, 128, 128, 128, 
 394                 128, 128, 128, 128, 128, 128, 128, 128, 
 395                 128, 128, 128, 128, 128, 128, 128, 128, 
 396                 128, 128, 128, 128, 128, 128, 128, 128, 
 397                 128, 128, 128, 128, 128, 128, 128, 128, 
 398                 128, 128, 128, 128, 128, 128, 128, 128, 
 399                 128, 128, 128, 128, 128, 128, 128, 128, 
 400         };
 401         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 402         yych = *YYCURSOR;
 403         if (yybm[0+yych] & 128) {
 404                 goto yy15;
 405         }
 406         ++YYCURSOR;
 407         { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }
 408 yy15:
 409         ++YYCURSOR;
 410         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 411         yych = *YYCURSOR;
 412         if (yybm[0+yych] & 128) {
 413                 goto yy15;
 414         }
 415         { passthru(STD_ARGS); goto state_plain; }
 416 }
 417 
 418 
 419 state_tag:
 420         start = YYCURSOR;
 421 
 422 {
 423         YYCTYPE yych;
 424         static const unsigned char yybm[] = {
 425                   0,   0,   0,   0,   0,   0,   0,   0, 
 426                   0,   0,   0,   0,   0,   0,   0,   0, 
 427                   0,   0,   0,   0,   0,   0,   0,   0, 
 428                   0,   0,   0,   0,   0,   0,   0,   0, 
 429                   0,   0,   0,   0,   0,   0,   0,   0, 
 430                   0,   0,   0,   0,   0,   0,   0,   0, 
 431                   0,   0,   0,   0,   0,   0,   0,   0, 
 432                   0,   0, 128,   0,   0,   0,   0,   0, 
 433                   0, 128, 128, 128, 128, 128, 128, 128, 
 434                 128, 128, 128, 128, 128, 128, 128, 128, 
 435                 128, 128, 128, 128, 128, 128, 128, 128, 
 436                 128, 128, 128,   0,   0,   0,   0,   0, 
 437                   0, 128, 128, 128, 128, 128, 128, 128, 
 438                 128, 128, 128, 128, 128, 128, 128, 128, 
 439                 128, 128, 128, 128, 128, 128, 128, 128, 
 440                 128, 128, 128,   0,   0,   0,   0,   0, 
 441                   0,   0,   0,   0,   0,   0,   0,   0, 
 442                   0,   0,   0,   0,   0,   0,   0,   0, 
 443                   0,   0,   0,   0,   0,   0,   0,   0, 
 444                   0,   0,   0,   0,   0,   0,   0,   0, 
 445                   0,   0,   0,   0,   0,   0,   0,   0, 
 446                   0,   0,   0,   0,   0,   0,   0,   0, 
 447                   0,   0,   0,   0,   0,   0,   0,   0, 
 448                   0,   0,   0,   0,   0,   0,   0,   0, 
 449                   0,   0,   0,   0,   0,   0,   0,   0, 
 450                   0,   0,   0,   0,   0,   0,   0,   0, 
 451                   0,   0,   0,   0,   0,   0,   0,   0, 
 452                   0,   0,   0,   0,   0,   0,   0,   0, 
 453                   0,   0,   0,   0,   0,   0,   0,   0, 
 454                   0,   0,   0,   0,   0,   0,   0,   0, 
 455                   0,   0,   0,   0,   0,   0,   0,   0, 
 456                   0,   0,   0,   0,   0,   0,   0,   0, 
 457         };
 458         if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
 459         yych = *YYCURSOR;
 460         if (yych <= '@') {
 461                 if (yych != ':') goto yy22;
 462         } else {
 463                 if (yych <= 'Z') goto yy20;
 464                 if (yych <= '`') goto yy22;
 465                 if (yych >= '{') goto yy22;
 466         }
 467 yy20:
 468         ++YYCURSOR;
 469         yych = *YYCURSOR;
 470         goto yy25;
 471 yy21:
 472         { handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; }
 473 yy22:
 474         ++YYCURSOR;
 475         { passthru(STD_ARGS); goto state_plain_begin; }
 476 yy24:
 477         ++YYCURSOR;
 478         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 479         yych = *YYCURSOR;
 480 yy25:
 481         if (yybm[0+yych] & 128) {
 482                 goto yy24;
 483         }
 484         goto yy21;
 485 }
 486 
 487 
 488 state_next_arg_begin:
 489         STATE = STATE_NEXT_ARG;
 490 
 491 state_next_arg:
 492         start = YYCURSOR;
 493 
 494 {
 495         YYCTYPE yych;
 496         static const unsigned char yybm[] = {
 497                   0,   0,   0,   0,   0,   0,   0,   0, 
 498                   0, 128, 128, 128,   0, 128,   0,   0, 
 499                   0,   0,   0,   0,   0,   0,   0,   0, 
 500                   0,   0,   0,   0,   0,   0,   0,   0, 
 501                 128,   0,   0,   0,   0,   0,   0,   0, 
 502                   0,   0,   0,   0,   0,   0,   0,   0, 
 503                   0,   0,   0,   0,   0,   0,   0,   0, 
 504                   0,   0,   0,   0,   0,   0,   0,   0, 
 505                   0,   0,   0,   0,   0,   0,   0,   0, 
 506                   0,   0,   0,   0,   0,   0,   0,   0, 
 507                   0,   0,   0,   0,   0,   0,   0,   0, 
 508                   0,   0,   0,   0,   0,   0,   0,   0, 
 509                   0,   0,   0,   0,   0,   0,   0,   0, 
 510                   0,   0,   0,   0,   0,   0,   0,   0, 
 511                   0,   0,   0,   0,   0,   0,   0,   0, 
 512                   0,   0,   0,   0,   0,   0,   0,   0, 
 513                   0,   0,   0,   0,   0,   0,   0,   0, 
 514                   0,   0,   0,   0,   0,   0,   0,   0, 
 515                   0,   0,   0,   0,   0,   0,   0,   0, 
 516                   0,   0,   0,   0,   0,   0,   0,   0, 
 517                   0,   0,   0,   0,   0,   0,   0,   0, 
 518                   0,   0,   0,   0,   0,   0,   0,   0, 
 519                   0,   0,   0,   0,   0,   0,   0,   0, 
 520                   0,   0,   0,   0,   0,   0,   0,   0, 
 521                   0,   0,   0,   0,   0,   0,   0,   0, 
 522                   0,   0,   0,   0,   0,   0,   0,   0, 
 523                   0,   0,   0,   0,   0,   0,   0,   0, 
 524                   0,   0,   0,   0,   0,   0,   0,   0, 
 525                   0,   0,   0,   0,   0,   0,   0,   0, 
 526                   0,   0,   0,   0,   0,   0,   0,   0, 
 527                   0,   0,   0,   0,   0,   0,   0,   0, 
 528                   0,   0,   0,   0,   0,   0,   0,   0, 
 529         };
 530         if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
 531         yych = *YYCURSOR;
 532         if (yych <= '.') {
 533                 if (yych <= '\f') {
 534                         if (yych <= 0x08) goto yy36;
 535                         if (yych <= '\v') goto yy32;
 536                         goto yy36;
 537                 } else {
 538                         if (yych <= '\r') goto yy32;
 539                         if (yych == ' ') goto yy32;
 540                         goto yy36;
 541                 }
 542         } else {
 543                 if (yych <= '@') {
 544                         if (yych <= '/') goto yy28;
 545                         if (yych == '>') goto yy30;
 546                         goto yy36;
 547                 } else {
 548                         if (yych <= 'Z') goto yy34;
 549                         if (yych <= '`') goto yy36;
 550                         if (yych <= 'z') goto yy34;
 551                         goto yy36;
 552                 }
 553         }
 554 yy28:
 555         ++YYCURSOR;
 556         if ((yych = *YYCURSOR) == '>') goto yy39;
 557 yy29:
 558         { passthru(STD_ARGS); goto state_plain_begin; }
 559 yy30:
 560         ++YYCURSOR;
 561 yy31:
 562         { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
 563 yy32:
 564         ++YYCURSOR;
 565         yych = *YYCURSOR;
 566         goto yy38;
 567 yy33:
 568         { passthru(STD_ARGS); goto state_next_arg; }
 569 yy34:
 570         ++YYCURSOR;
 571         { --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
 572 yy36:
 573         yych = *++YYCURSOR;
 574         goto yy29;
 575 yy37:
 576         ++YYCURSOR;
 577         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 578         yych = *YYCURSOR;
 579 yy38:
 580         if (yybm[0+yych] & 128) {
 581                 goto yy37;
 582         }
 583         goto yy33;
 584 yy39:
 585         ++YYCURSOR;
 586         yych = *YYCURSOR;
 587         goto yy31;
 588 }
 589 
 590 
 591 state_arg:
 592         start = YYCURSOR;
 593 
 594 {
 595         YYCTYPE yych;
 596         static const unsigned char yybm[] = {
 597                   0,   0,   0,   0,   0,   0,   0,   0, 
 598                   0,   0,   0,   0,   0,   0,   0,   0, 
 599                   0,   0,   0,   0,   0,   0,   0,   0, 
 600                   0,   0,   0,   0,   0,   0,   0,   0, 
 601                   0,   0,   0,   0,   0,   0,   0,   0, 
 602                   0,   0,   0,   0,   0, 128,   0,   0, 
 603                   0,   0,   0,   0,   0,   0,   0,   0, 
 604                   0,   0,   0,   0,   0,   0,   0,   0, 
 605                   0, 128, 128, 128, 128, 128, 128, 128, 
 606                 128, 128, 128, 128, 128, 128, 128, 128, 
 607                 128, 128, 128, 128, 128, 128, 128, 128, 
 608                 128, 128, 128,   0,   0,   0,   0,   0, 
 609                   0, 128, 128, 128, 128, 128, 128, 128, 
 610                 128, 128, 128, 128, 128, 128, 128, 128, 
 611                 128, 128, 128, 128, 128, 128, 128, 128, 
 612                 128, 128, 128,   0,   0,   0,   0,   0, 
 613                   0,   0,   0,   0,   0,   0,   0,   0, 
 614                   0,   0,   0,   0,   0,   0,   0,   0, 
 615                   0,   0,   0,   0,   0,   0,   0,   0, 
 616                   0,   0,   0,   0,   0,   0,   0,   0, 
 617                   0,   0,   0,   0,   0,   0,   0,   0, 
 618                   0,   0,   0,   0,   0,   0,   0,   0, 
 619                   0,   0,   0,   0,   0,   0,   0,   0, 
 620                   0,   0,   0,   0,   0,   0,   0,   0, 
 621                   0,   0,   0,   0,   0,   0,   0,   0, 
 622                   0,   0,   0,   0,   0,   0,   0,   0, 
 623                   0,   0,   0,   0,   0,   0,   0,   0, 
 624                   0,   0,   0,   0,   0,   0,   0,   0, 
 625                   0,   0,   0,   0,   0,   0,   0,   0, 
 626                   0,   0,   0,   0,   0,   0,   0,   0, 
 627                   0,   0,   0,   0,   0,   0,   0,   0, 
 628                   0,   0,   0,   0,   0,   0,   0,   0, 
 629         };
 630         if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
 631         yych = *YYCURSOR;
 632         if (yych <= '@') goto yy44;
 633         if (yych <= 'Z') goto yy42;
 634         if (yych <= '`') goto yy44;
 635         if (yych >= '{') goto yy44;
 636 yy42:
 637         ++YYCURSOR;
 638         yych = *YYCURSOR;
 639         goto yy47;
 640 yy43:
 641         { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
 642 yy44:
 643         ++YYCURSOR;
 644         { passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
 645 yy46:
 646         ++YYCURSOR;
 647         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 648         yych = *YYCURSOR;
 649 yy47:
 650         if (yybm[0+yych] & 128) {
 651                 goto yy46;
 652         }
 653         goto yy43;
 654 }
 655 
 656 
 657 state_before_val:
 658         start = YYCURSOR;
 659 
 660 {
 661         YYCTYPE yych;
 662         static const unsigned char yybm[] = {
 663                   0,   0,   0,   0,   0,   0,   0,   0, 
 664                   0,   0,   0,   0,   0,   0,   0,   0, 
 665                   0,   0,   0,   0,   0,   0,   0,   0, 
 666                   0,   0,   0,   0,   0,   0,   0,   0, 
 667                 128,   0,   0,   0,   0,   0,   0,   0, 
 668                   0,   0,   0,   0,   0,   0,   0,   0, 
 669                   0,   0,   0,   0,   0,   0,   0,   0, 
 670                   0,   0,   0,   0,   0,   0,   0,   0, 
 671                   0,   0,   0,   0,   0,   0,   0,   0, 
 672                   0,   0,   0,   0,   0,   0,   0,   0, 
 673                   0,   0,   0,   0,   0,   0,   0,   0, 
 674                   0,   0,   0,   0,   0,   0,   0,   0, 
 675                   0,   0,   0,   0,   0,   0,   0,   0, 
 676                   0,   0,   0,   0,   0,   0,   0,   0, 
 677                   0,   0,   0,   0,   0,   0,   0,   0, 
 678                   0,   0,   0,   0,   0,   0,   0,   0, 
 679                   0,   0,   0,   0,   0,   0,   0,   0, 
 680                   0,   0,   0,   0,   0,   0,   0,   0, 
 681                   0,   0,   0,   0,   0,   0,   0,   0, 
 682                   0,   0,   0,   0,   0,   0,   0,   0, 
 683                   0,   0,   0,   0,   0,   0,   0,   0, 
 684                   0,   0,   0,   0,   0,   0,   0,   0, 
 685                   0,   0,   0,   0,   0,   0,   0,   0, 
 686                   0,   0,   0,   0,   0,   0,   0,   0, 
 687                   0,   0,   0,   0,   0,   0,   0,   0, 
 688                   0,   0,   0,   0,   0,   0,   0,   0, 
 689                   0,   0,   0,   0,   0,   0,   0,   0, 
 690                   0,   0,   0,   0,   0,   0,   0,   0, 
 691                   0,   0,   0,   0,   0,   0,   0,   0, 
 692                   0,   0,   0,   0,   0,   0,   0,   0, 
 693                   0,   0,   0,   0,   0,   0,   0,   0, 
 694                   0,   0,   0,   0,   0,   0,   0,   0, 
 695         };
 696         if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
 697         yych = *YYCURSOR;
 698         if (yych == ' ') goto yy50;
 699         if (yych == '=') goto yy52;
 700         goto yy54;
 701 yy50:
 702         yych = *(YYMARKER = ++YYCURSOR);
 703         if (yych == ' ') goto yy57;
 704         if (yych == '=') goto yy55;
 705 yy51:
 706         { --YYCURSOR; goto state_next_arg_begin; }
 707 yy52:
 708         ++YYCURSOR;
 709         yych = *YYCURSOR;
 710         goto yy56;
 711 yy53:
 712         { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
 713 yy54:
 714         yych = *++YYCURSOR;
 715         goto yy51;
 716 yy55:
 717         ++YYCURSOR;
 718         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 719         yych = *YYCURSOR;
 720 yy56:
 721         if (yybm[0+yych] & 128) {
 722                 goto yy55;
 723         }
 724         goto yy53;
 725 yy57:
 726         ++YYCURSOR;
 727         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 728         yych = *YYCURSOR;
 729         if (yych == ' ') goto yy57;
 730         if (yych == '=') goto yy55;
 731         YYCURSOR = YYMARKER;
 732         goto yy51;
 733 }
 734 
 735 
 736 
 737 state_val:
 738         start = YYCURSOR;
 739 
 740 {
 741         YYCTYPE yych;
 742         static const unsigned char yybm[] = {
 743                 224, 224, 224, 224, 224, 224, 224, 224, 
 744                 224, 192, 192, 224, 224, 192, 224, 224, 
 745                 224, 224, 224, 224, 224, 224, 224, 224, 
 746                 224, 224, 224, 224, 224, 224, 224, 224, 
 747                 192, 224,  64, 224, 224, 224, 224, 128, 
 748                 224, 224, 224, 224, 224, 224, 224, 224, 
 749                 224, 224, 224, 224, 224, 224, 224, 224, 
 750                 224, 224, 224, 224, 224, 224,   0, 224, 
 751                 224, 224, 224, 224, 224, 224, 224, 224, 
 752                 224, 224, 224, 224, 224, 224, 224, 224, 
 753                 224, 224, 224, 224, 224, 224, 224, 224, 
 754                 224, 224, 224, 224, 224, 224, 224, 224, 
 755                 224, 224, 224, 224, 224, 224, 224, 224, 
 756                 224, 224, 224, 224, 224, 224, 224, 224, 
 757                 224, 224, 224, 224, 224, 224, 224, 224, 
 758                 224, 224, 224, 224, 224, 224, 224, 224, 
 759                 224, 224, 224, 224, 224, 224, 224, 224, 
 760                 224, 224, 224, 224, 224, 224, 224, 224, 
 761                 224, 224, 224, 224, 224, 224, 224, 224, 
 762                 224, 224, 224, 224, 224, 224, 224, 224, 
 763                 224, 224, 224, 224, 224, 224, 224, 224, 
 764                 224, 224, 224, 224, 224, 224, 224, 224, 
 765                 224, 224, 224, 224, 224, 224, 224, 224, 
 766                 224, 224, 224, 224, 224, 224, 224, 224, 
 767                 224, 224, 224, 224, 224, 224, 224, 224, 
 768                 224, 224, 224, 224, 224, 224, 224, 224, 
 769                 224, 224, 224, 224, 224, 224, 224, 224, 
 770                 224, 224, 224, 224, 224, 224, 224, 224, 
 771                 224, 224, 224, 224, 224, 224, 224, 224, 
 772                 224, 224, 224, 224, 224, 224, 224, 224, 
 773                 224, 224, 224, 224, 224, 224, 224, 224, 
 774                 224, 224, 224, 224, 224, 224, 224, 224, 
 775         };
 776         if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
 777         yych = *YYCURSOR;
 778         if (yych <= ' ') {
 779                 if (yych <= '\f') {
 780                         if (yych <= 0x08) goto yy65;
 781                         if (yych <= '\n') goto yy67;
 782                         goto yy65;
 783                 } else {
 784                         if (yych <= '\r') goto yy67;
 785                         if (yych <= 0x1F) goto yy65;
 786                         goto yy67;
 787                 }
 788         } else {
 789                 if (yych <= '&') {
 790                         if (yych != '"') goto yy65;
 791                 } else {
 792                         if (yych <= '\'') goto yy64;
 793                         if (yych == '>') goto yy67;
 794                         goto yy65;
 795                 }
 796         }
 797         yych = *(YYMARKER = ++YYCURSOR);
 798         if (yych != '>') goto yy76;
 799 yy63:
 800         { passthru(STD_ARGS); goto state_next_arg_begin; }
 801 yy64:
 802         yych = *(YYMARKER = ++YYCURSOR);
 803         if (yych == '>') goto yy63;
 804         goto yy71;
 805 yy65:
 806         ++YYCURSOR;
 807         yych = *YYCURSOR;
 808         goto yy69;
 809 yy66:
 810         { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
 811 yy67:
 812         yych = *++YYCURSOR;
 813         goto yy63;
 814 yy68:
 815         ++YYCURSOR;
 816         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 817         yych = *YYCURSOR;
 818 yy69:
 819         if (yybm[0+yych] & 32) {
 820                 goto yy68;
 821         }
 822         goto yy66;
 823 yy70:
 824         ++YYCURSOR;
 825         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 826         yych = *YYCURSOR;
 827 yy71:
 828         if (yybm[0+yych] & 64) {
 829                 goto yy70;
 830         }
 831         if (yych <= '=') goto yy73;
 832 yy72:
 833         YYCURSOR = YYMARKER;
 834         goto yy63;
 835 yy73:
 836         ++YYCURSOR;
 837         { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
 838 yy75:
 839         ++YYCURSOR;
 840         if (YYLIMIT <= YYCURSOR) YYFILL(1);
 841         yych = *YYCURSOR;
 842 yy76:
 843         if (yybm[0+yych] & 128) {
 844                 goto yy75;
 845         }
 846         if (yych >= '>') goto yy72;
 847         ++YYCURSOR;
 848         { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
 849 }
 850 
 851 
 852 stop:
 853         if (YYLIMIT < start) {
 854                 /* XXX: Crash avoidance. Need to work with reporter to figure out what goes wrong */
 855                 rest = 0;
 856         } else {
 857                 rest = YYLIMIT - start;
 858                 scdebug(("stopped in state %d at pos %d (%d:%c) %d\n", STATE, YYCURSOR - ctx->buf.c, *YYCURSOR, *YYCURSOR, rest));
 859         }
 860 
 861         if (rest) memmove(ZSTR_VAL(ctx->buf.s), start, rest);
 862         ZSTR_LEN(ctx->buf.s) = rest;
 863 }
 864 
 865 
 866 PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen, int urlencode)
 867 {
 868         char *result;
 869         smart_str surl = {0};
 870         smart_str buf = {0};
 871         smart_str url_app = {0};
 872         zend_string *encoded;
 873 
 874         smart_str_appendl(&surl, url, urllen);
 875 
 876         if (urlencode) {
 877                 encoded = php_raw_url_encode(name, strlen(name));
 878                 smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
 879                 zend_string_free(encoded);
 880         } else {
 881                 smart_str_appends(&url_app, name);
 882         }
 883         smart_str_appendc(&url_app, '=');
 884         if (urlencode) {
 885                 encoded = php_raw_url_encode(value, strlen(value));
 886                 smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
 887                 zend_string_free(encoded);
 888         } else {
 889                 smart_str_appends(&url_app, value);
 890         }
 891 
 892         append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output);
 893 
 894         smart_str_0(&buf);
 895         if (newlen) *newlen = ZSTR_LEN(buf.s);
 896         result = estrndup(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s));
 897 
 898         smart_str_free(&url_app);
 899         smart_str_free(&buf);
 900 
 901         return result;
 902 }
 903 
 904 
 905 static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_bool do_flush)
 906 {
 907         url_adapt_state_ex_t *ctx;
 908         char *retval;
 909 
 910         ctx = &BG(url_adapt_state_ex);
 911 
 912         xx_mainloop(ctx, src, srclen);
 913 
 914         if (!ctx->result.s) {
 915                 smart_str_appendl(&ctx->result, "", 0);
 916                 *newlen = 0;
 917         } else {
 918                 *newlen = ZSTR_LEN(ctx->result.s);
 919         }
 920         smart_str_0(&ctx->result);
 921         if (do_flush) {
 922                 smart_str_append(&ctx->result, ctx->buf.s);
 923                 *newlen += ZSTR_LEN(ctx->buf.s);
 924                 smart_str_free(&ctx->buf);
 925                 smart_str_free(&ctx->val);
 926         }
 927         retval = estrndup(ZSTR_VAL(ctx->result.s), ZSTR_LEN(ctx->result.s));
 928         smart_str_free(&ctx->result);
 929         return retval;
 930 }
 931 
 932 static int php_url_scanner_ex_activate(void)
 933 {
 934         url_adapt_state_ex_t *ctx;
 935 
 936         ctx = &BG(url_adapt_state_ex);
 937 
 938         memset(ctx, 0, ((size_t) &((url_adapt_state_ex_t *)0)->tags));
 939 
 940         return SUCCESS;
 941 }
 942 
 943 static int php_url_scanner_ex_deactivate(void)
 944 {
 945         url_adapt_state_ex_t *ctx;
 946 
 947         ctx = &BG(url_adapt_state_ex);
 948 
 949         smart_str_free(&ctx->result);
 950         smart_str_free(&ctx->buf);
 951         smart_str_free(&ctx->tag);
 952         smart_str_free(&ctx->arg);
 953 
 954         return SUCCESS;
 955 }
 956 
 957 static void php_url_scanner_output_handler(char *output, size_t output_len, char **handled_output, size_t *handled_output_len, int mode)
 958 {
 959         size_t len;
 960 
 961         if (ZSTR_LEN(BG(url_adapt_state_ex).url_app.s) != 0) {
 962                 *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));
 963                 if (sizeof(uint) < sizeof(size_t)) {
 964                         if (len > UINT_MAX)
 965                                 len = UINT_MAX;
 966                 }
 967                 *handled_output_len = len;
 968         } else if (ZSTR_LEN(BG(url_adapt_state_ex).url_app.s) == 0) {
 969                 url_adapt_state_ex_t *ctx = &BG(url_adapt_state_ex);
 970                 if (ctx->buf.s && ZSTR_LEN(ctx->buf.s)) {
 971                         smart_str_append(&ctx->result, ctx->buf.s);
 972                         smart_str_appendl(&ctx->result, output, output_len);
 973 
 974                         *handled_output = estrndup(ZSTR_VAL(ctx->result.s), ZSTR_LEN(ctx->result.s));
 975                         *handled_output_len = ZSTR_LEN(ctx->buf.s) + output_len;
 976 
 977                         smart_str_free(&ctx->buf);
 978                         smart_str_free(&ctx->result);
 979                 } else {
 980                         *handled_output = estrndup(output, *handled_output_len = output_len);
 981                 }
 982         } else {
 983                 *handled_output = NULL;
 984         }
 985 }
 986 
 987 PHPAPI int php_url_scanner_add_var(char *name, size_t name_len, char *value, size_t value_len, int urlencode)
 988 {
 989         smart_str sname = {0};
 990         smart_str svalue = {0};
 991         zend_string *encoded;
 992 
 993         if (!BG(url_adapt_state_ex).active) {
 994                 php_url_scanner_ex_activate();
 995                 php_output_start_internal(ZEND_STRL("URL-Rewriter"), php_url_scanner_output_handler, 0, PHP_OUTPUT_HANDLER_STDFLAGS);
 996                 BG(url_adapt_state_ex).active = 1;
 997         }
 998 
 999         if (BG(url_adapt_state_ex).url_app.s && ZSTR_LEN(BG(url_adapt_state_ex).url_app.s) != 0) {
1000                 smart_str_appends(&BG(url_adapt_state_ex).url_app, PG(arg_separator).output);
1001         }
1002 
1003         if (urlencode) {
1004                 encoded = php_raw_url_encode(name, name_len);
1005                 smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
1006                 zend_string_free(encoded);
1007                 encoded = php_raw_url_encode(value, value_len);
1008                 smart_str_appendl(&svalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
1009                 zend_string_free(encoded);
1010         } else {
1011                 smart_str_appendl(&sname, name, name_len);
1012                 smart_str_appendl(&svalue, value, value_len);
1013         }
1014 
1015         smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &sname);
1016         smart_str_appendc(&BG(url_adapt_state_ex).url_app, '=');
1017         smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &svalue);
1018 
1019         smart_str_appends(&BG(url_adapt_state_ex).form_app, "<input type=\"hidden\" name=\"");
1020         smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &sname);
1021         smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" value=\"");
1022         smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &svalue);
1023         smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" />");
1024 
1025         smart_str_free(&sname);
1026         smart_str_free(&svalue);
1027 
1028         return SUCCESS;
1029 }
1030 
1031 PHPAPI int php_url_scanner_reset_vars(void)
1032 {
1033         if (BG(url_adapt_state_ex).form_app.s) {
1034                 ZSTR_LEN(BG(url_adapt_state_ex).form_app.s) = 0;
1035         }
1036         if (BG(url_adapt_state_ex).url_app.s) {
1037                 ZSTR_LEN(BG(url_adapt_state_ex).url_app.s) = 0;
1038         }
1039 
1040         return SUCCESS;
1041 }
1042 
1043 PHP_MINIT_FUNCTION(url_scanner)
1044 {
1045         BG(url_adapt_state_ex).tags = NULL;
1046 
1047         BG(url_adapt_state_ex).form_app.s = BG(url_adapt_state_ex).url_app.s = NULL;
1048 
1049         REGISTER_INI_ENTRIES();
1050         return SUCCESS;
1051 }
1052 
1053 PHP_MSHUTDOWN_FUNCTION(url_scanner)
1054 {
1055         UNREGISTER_INI_ENTRIES();
1056 
1057         return SUCCESS;
1058 }
1059 
1060 PHP_RINIT_FUNCTION(url_scanner)
1061 {
1062         BG(url_adapt_state_ex).active = 0;
1063 
1064         return SUCCESS;
1065 }
1066 
1067 PHP_RSHUTDOWN_FUNCTION(url_scanner)
1068 {
1069         if (BG(url_adapt_state_ex).active) {
1070                 php_url_scanner_ex_deactivate();
1071                 BG(url_adapt_state_ex).active = 0;
1072         }
1073 
1074         smart_str_free(&BG(url_adapt_state_ex).form_app);
1075         smart_str_free(&BG(url_adapt_state_ex).url_app);
1076 
1077         return SUCCESS;
1078 }

/* [<][>][^][v][top][bottom][index][help] */