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