root/ext/standard/url_scanner_ex.c

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

DEFINITIONS

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

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

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