File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard / url_scanner_ex.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:57 2014 UTC (10 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /* Generated by re2c 0.13.5 */
    2: /*
    3:   +----------------------------------------------------------------------+
    4:   | PHP Version 5                                                        |
    5:   +----------------------------------------------------------------------+
    6:   | Copyright (c) 1997-2014 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,v 1.1.1.5 2014/06/15 20:03:57 misho Exp $ */
   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 yy34;
  525: 			if (yych <= '\v') goto yy30;
  526: 			goto yy34;
  527: 		} else {
  528: 			if (yych <= '\r') goto yy30;
  529: 			if (yych <= 0x1F) goto yy34;
  530: 			goto yy30;
  531: 		}
  532: 	} else {
  533: 		if (yych <= '@') {
  534: 			if (yych != '>') goto yy34;
  535: 		} else {
  536: 			if (yych <= 'Z') goto yy32;
  537: 			if (yych <= '`') goto yy34;
  538: 			if (yych <= 'z') goto yy32;
  539: 			goto yy34;
  540: 		}
  541: 	}
  542: 	++YYCURSOR;
  543: 	{ passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
  544: yy30:
  545: 	++YYCURSOR;
  546: 	yych = *YYCURSOR;
  547: 	goto yy37;
  548: yy31:
  549: 	{ passthru(STD_ARGS); goto state_next_arg; }
  550: yy32:
  551: 	++YYCURSOR;
  552: 	{ --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
  553: yy34:
  554: 	++YYCURSOR;
  555: 	{ passthru(STD_ARGS); goto state_plain_begin; }
  556: yy36:
  557: 	++YYCURSOR;
  558: 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
  559: 	yych = *YYCURSOR;
  560: yy37:
  561: 	if (yybm[0+yych] & 128) {
  562: 		goto yy36;
  563: 	}
  564: 	goto yy31;
  565: }
  566: 
  567: 
  568: state_arg:
  569: 	start = YYCURSOR;
  570: 
  571: {
  572: 	YYCTYPE yych;
  573: 	static const unsigned char yybm[] = {
  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,   0,   0,   0, 
  579: 		  0,   0,   0,   0,   0, 128,   0,   0, 
  580: 		  0,   0,   0,   0,   0,   0,   0,   0, 
  581: 		  0,   0,   0,   0,   0,   0,   0,   0, 
  582: 		  0, 128, 128, 128, 128, 128, 128, 128, 
  583: 		128, 128, 128, 128, 128, 128, 128, 128, 
  584: 		128, 128, 128, 128, 128, 128, 128, 128, 
  585: 		128, 128, 128,   0,   0,   0,   0,   0, 
  586: 		  0, 128, 128, 128, 128, 128, 128, 128, 
  587: 		128, 128, 128, 128, 128, 128, 128, 128, 
  588: 		128, 128, 128, 128, 128, 128, 128, 128, 
  589: 		128, 128, 128,   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: 		  0,   0,   0,   0,   0,   0,   0,   0, 
  606: 	};
  607: 	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
  608: 	yych = *YYCURSOR;
  609: 	if (yych <= '@') goto yy42;
  610: 	if (yych <= 'Z') goto yy40;
  611: 	if (yych <= '`') goto yy42;
  612: 	if (yych >= '{') goto yy42;
  613: yy40:
  614: 	++YYCURSOR;
  615: 	yych = *YYCURSOR;
  616: 	goto yy45;
  617: yy41:
  618: 	{ passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
  619: yy42:
  620: 	++YYCURSOR;
  621: 	{ passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
  622: yy44:
  623: 	++YYCURSOR;
  624: 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
  625: 	yych = *YYCURSOR;
  626: yy45:
  627: 	if (yybm[0+yych] & 128) {
  628: 		goto yy44;
  629: 	}
  630: 	goto yy41;
  631: }
  632: 
  633: 
  634: state_before_val:
  635: 	start = YYCURSOR;
  636: 
  637: {
  638: 	YYCTYPE yych;
  639: 	static const unsigned char yybm[] = {
  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: 		  0,   0,   0,   0,   0,   0,   0,   0, 
  644: 		128,   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: 		  0,   0,   0,   0,   0,   0,   0,   0, 
  672: 	};
  673: 	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
  674: 	yych = *YYCURSOR;
  675: 	if (yych == ' ') goto yy48;
  676: 	if (yych == '=') goto yy50;
  677: 	goto yy52;
  678: yy48:
  679: 	yych = *(YYMARKER = ++YYCURSOR);
  680: 	if (yych == ' ') goto yy55;
  681: 	if (yych == '=') goto yy53;
  682: yy49:
  683: 	{ --YYCURSOR; goto state_next_arg_begin; }
  684: yy50:
  685: 	++YYCURSOR;
  686: 	yych = *YYCURSOR;
  687: 	goto yy54;
  688: yy51:
  689: 	{ passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
  690: yy52:
  691: 	yych = *++YYCURSOR;
  692: 	goto yy49;
  693: yy53:
  694: 	++YYCURSOR;
  695: 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
  696: 	yych = *YYCURSOR;
  697: yy54:
  698: 	if (yybm[0+yych] & 128) {
  699: 		goto yy53;
  700: 	}
  701: 	goto yy51;
  702: yy55:
  703: 	++YYCURSOR;
  704: 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
  705: 	yych = *YYCURSOR;
  706: 	if (yych == ' ') goto yy55;
  707: 	if (yych == '=') goto yy53;
  708: 	YYCURSOR = YYMARKER;
  709: 	goto yy49;
  710: }
  711: 
  712: 
  713: 
  714: state_val:
  715: 	start = YYCURSOR;
  716: 
  717: {
  718: 	YYCTYPE yych;
  719: 	static const unsigned char yybm[] = {
  720: 		224, 224, 224, 224, 224, 224, 224, 224, 
  721: 		224, 192, 192, 224, 224, 192, 224, 224, 
  722: 		224, 224, 224, 224, 224, 224, 224, 224, 
  723: 		224, 224, 224, 224, 224, 224, 224, 224, 
  724: 		192, 224,  64, 224, 224, 224, 224, 128, 
  725: 		224, 224, 224, 224, 224, 224, 224, 224, 
  726: 		224, 224, 224, 224, 224, 224, 224, 224, 
  727: 		224, 224, 224, 224, 224, 224,   0, 224, 
  728: 		224, 224, 224, 224, 224, 224, 224, 224, 
  729: 		224, 224, 224, 224, 224, 224, 224, 224, 
  730: 		224, 224, 224, 224, 224, 224, 224, 224, 
  731: 		224, 224, 224, 224, 224, 224, 224, 224, 
  732: 		224, 224, 224, 224, 224, 224, 224, 224, 
  733: 		224, 224, 224, 224, 224, 224, 224, 224, 
  734: 		224, 224, 224, 224, 224, 224, 224, 224, 
  735: 		224, 224, 224, 224, 224, 224, 224, 224, 
  736: 		224, 224, 224, 224, 224, 224, 224, 224, 
  737: 		224, 224, 224, 224, 224, 224, 224, 224, 
  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, 224, 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: 	};
  753: 	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
  754: 	yych = *YYCURSOR;
  755: 	if (yych <= ' ') {
  756: 		if (yych <= '\f') {
  757: 			if (yych <= 0x08) goto yy63;
  758: 			if (yych <= '\n') goto yy65;
  759: 			goto yy63;
  760: 		} else {
  761: 			if (yych <= '\r') goto yy65;
  762: 			if (yych <= 0x1F) goto yy63;
  763: 			goto yy65;
  764: 		}
  765: 	} else {
  766: 		if (yych <= '&') {
  767: 			if (yych != '"') goto yy63;
  768: 		} else {
  769: 			if (yych <= '\'') goto yy62;
  770: 			if (yych == '>') goto yy65;
  771: 			goto yy63;
  772: 		}
  773: 	}
  774: 	yych = *(YYMARKER = ++YYCURSOR);
  775: 	if (yych != '>') goto yy74;
  776: yy61:
  777: 	{ passthru(STD_ARGS); goto state_next_arg_begin; }
  778: yy62:
  779: 	yych = *(YYMARKER = ++YYCURSOR);
  780: 	if (yych == '>') goto yy61;
  781: 	goto yy69;
  782: yy63:
  783: 	++YYCURSOR;
  784: 	yych = *YYCURSOR;
  785: 	goto yy67;
  786: yy64:
  787: 	{ handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
  788: yy65:
  789: 	yych = *++YYCURSOR;
  790: 	goto yy61;
  791: yy66:
  792: 	++YYCURSOR;
  793: 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
  794: 	yych = *YYCURSOR;
  795: yy67:
  796: 	if (yybm[0+yych] & 32) {
  797: 		goto yy66;
  798: 	}
  799: 	goto yy64;
  800: yy68:
  801: 	++YYCURSOR;
  802: 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
  803: 	yych = *YYCURSOR;
  804: yy69:
  805: 	if (yybm[0+yych] & 64) {
  806: 		goto yy68;
  807: 	}
  808: 	if (yych <= '=') goto yy71;
  809: yy70:
  810: 	YYCURSOR = YYMARKER;
  811: 	goto yy61;
  812: yy71:
  813: 	++YYCURSOR;
  814: 	{ handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
  815: yy73:
  816: 	++YYCURSOR;
  817: 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
  818: 	yych = *YYCURSOR;
  819: yy74:
  820: 	if (yybm[0+yych] & 128) {
  821: 		goto yy73;
  822: 	}
  823: 	if (yych >= '>') goto yy70;
  824: 	++YYCURSOR;
  825: 	{ handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
  826: }
  827: 
  828: 
  829: stop:
  830: 	rest = YYLIMIT - start;
  831: 	scdebug(("stopped in state %d at pos %d (%d:%c) %d\n", STATE, YYCURSOR - ctx->buf.c, *YYCURSOR, *YYCURSOR, rest));
  832: 	/* XXX: Crash avoidance. Need to work with reporter to figure out what goes wrong */	
  833: 	if (rest < 0) rest = 0;
  834: 	
  835: 	if (rest) memmove(ctx->buf.c, start, rest);
  836: 	ctx->buf.len = rest;
  837: }
  838: 
  839: char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen TSRMLS_DC)
  840: {
  841: 	smart_str surl = {0};
  842: 	smart_str buf = {0};
  843: 	smart_str url_app = {0};
  844: 
  845: 	smart_str_setl(&surl, url, urllen);
  846: 
  847: 	smart_str_appends(&url_app, name);
  848: 	smart_str_appendc(&url_app, '=');
  849: 	smart_str_appends(&url_app, value);
  850: 
  851: 	append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output);
  852: 
  853: 	smart_str_0(&buf);
  854: 	if (newlen) *newlen = buf.len;
  855: 
  856: 	smart_str_free(&url_app);
  857: 
  858: 	return buf.c;
  859: }
  860: 
  861: 
  862: static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_bool do_flush TSRMLS_DC)
  863: {
  864: 	url_adapt_state_ex_t *ctx;
  865: 	char *retval;
  866: 
  867: 	ctx = &BG(url_adapt_state_ex);
  868: 
  869: 	xx_mainloop(ctx, src, srclen TSRMLS_CC);
  870: 
  871: 	*newlen = ctx->result.len;
  872: 	if (!ctx->result.c) {
  873: 		smart_str_appendl(&ctx->result, "", 0);
  874: 	}
  875: 	smart_str_0(&ctx->result);
  876: 	if (do_flush) {
  877: 		smart_str_appendl(&ctx->result, ctx->buf.c, ctx->buf.len);
  878: 		*newlen += ctx->buf.len;
  879: 		smart_str_free(&ctx->buf);
  880: 	}
  881: 	retval = ctx->result.c;
  882: 	ctx->result.c = NULL;
  883: 	ctx->result.len = 0;
  884: 	return retval;
  885: }
  886: 
  887: static int php_url_scanner_ex_activate(TSRMLS_D)
  888: {
  889: 	url_adapt_state_ex_t *ctx;
  890: 	
  891: 	ctx = &BG(url_adapt_state_ex);
  892: 
  893: 	memset(ctx, 0, ((size_t) &((url_adapt_state_ex_t *)0)->tags));
  894: 
  895: 	return SUCCESS;
  896: }
  897: 
  898: static int php_url_scanner_ex_deactivate(TSRMLS_D)
  899: {
  900: 	url_adapt_state_ex_t *ctx;
  901: 	
  902: 	ctx = &BG(url_adapt_state_ex);
  903: 
  904: 	smart_str_free(&ctx->result);
  905: 	smart_str_free(&ctx->buf);
  906: 	smart_str_free(&ctx->tag);
  907: 	smart_str_free(&ctx->arg);
  908: 
  909: 	return SUCCESS;
  910: }
  911: 
  912: static void php_url_scanner_output_handler(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
  913: {
  914: 	size_t len;
  915: 
  916: 	if (BG(url_adapt_state_ex).url_app.len != 0) {
  917: 		*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);
  918: 		if (sizeof(uint) < sizeof(size_t)) {
  919: 			if (len > UINT_MAX)
  920: 				len = UINT_MAX;
  921: 		}
  922: 		*handled_output_len = len;
  923: 	} else if (BG(url_adapt_state_ex).url_app.len == 0) {
  924: 		url_adapt_state_ex_t *ctx = &BG(url_adapt_state_ex);
  925: 		if (ctx->buf.len) {
  926: 			smart_str_appendl(&ctx->result, ctx->buf.c, ctx->buf.len);
  927: 			smart_str_appendl(&ctx->result, output, output_len);
  928: 
  929: 			*handled_output = ctx->result.c;
  930: 			*handled_output_len = ctx->buf.len + output_len;
  931: 
  932: 			ctx->result.c = NULL;
  933: 			ctx->result.len = 0;
  934: 			smart_str_free(&ctx->buf);
  935: 		} else {
  936: 			*handled_output = estrndup(output, *handled_output_len = output_len);
  937: 		}
  938: 	} else {
  939: 		*handled_output = NULL;
  940: 	}
  941: }
  942: 
  943: PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC)
  944: {
  945: 	char *encoded;
  946: 	int encoded_len;
  947: 	smart_str val;
  948: 	
  949: 	if (! BG(url_adapt_state_ex).active) {
  950: 		php_url_scanner_ex_activate(TSRMLS_C);
  951: 		php_output_start_internal(ZEND_STRL("URL-Rewriter"), php_url_scanner_output_handler, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC);
  952: 		BG(url_adapt_state_ex).active = 1;
  953: 	}
  954: 
  955: 
  956: 	if (BG(url_adapt_state_ex).url_app.len != 0) {
  957: 		smart_str_appends(&BG(url_adapt_state_ex).url_app, PG(arg_separator).output);
  958: 	}
  959: 
  960: 	if (urlencode) {
  961: 		encoded = php_url_encode(value, value_len, &encoded_len);
  962: 		smart_str_setl(&val, encoded, encoded_len);
  963: 	} else {
  964: 		smart_str_setl(&val, value, value_len);
  965: 	}
  966: 	
  967: 	smart_str_appendl(&BG(url_adapt_state_ex).url_app, name, name_len);
  968: 	smart_str_appendc(&BG(url_adapt_state_ex).url_app, '=');
  969: 	smart_str_append(&BG(url_adapt_state_ex).url_app, &val);
  970: 
  971: 	smart_str_appends(&BG(url_adapt_state_ex).form_app, "<input type=\"hidden\" name=\""); 
  972: 	smart_str_appendl(&BG(url_adapt_state_ex).form_app, name, name_len);
  973: 	smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" value=\"");
  974: 	smart_str_append(&BG(url_adapt_state_ex).form_app, &val);
  975: 	smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" />");
  976: 
  977: 	if (urlencode)
  978: 		efree(encoded);
  979: 
  980: 	return SUCCESS;
  981: }
  982: 
  983: PHPAPI int php_url_scanner_reset_vars(TSRMLS_D)
  984: {
  985: 	BG(url_adapt_state_ex).form_app.len = 0;
  986: 	BG(url_adapt_state_ex).url_app.len = 0;
  987: 
  988: 	return SUCCESS;
  989: }
  990: 
  991: PHP_MINIT_FUNCTION(url_scanner)
  992: {
  993: 	BG(url_adapt_state_ex).tags = NULL;
  994: 
  995: 	BG(url_adapt_state_ex).form_app.c = BG(url_adapt_state_ex).url_app.c = 0;
  996: 	BG(url_adapt_state_ex).form_app.len = BG(url_adapt_state_ex).url_app.len = 0;
  997: 
  998: 	REGISTER_INI_ENTRIES();
  999: 	return SUCCESS;
 1000: }
 1001: 
 1002: PHP_MSHUTDOWN_FUNCTION(url_scanner)
 1003: {
 1004: 	UNREGISTER_INI_ENTRIES();
 1005: 
 1006: 	return SUCCESS;
 1007: }
 1008: 
 1009: PHP_RINIT_FUNCTION(url_scanner)
 1010: {
 1011: 	BG(url_adapt_state_ex).active = 0;
 1012: 	
 1013: 	return SUCCESS;
 1014: }
 1015: 
 1016: PHP_RSHUTDOWN_FUNCTION(url_scanner)
 1017: {
 1018: 	if (BG(url_adapt_state_ex).active) {
 1019: 		php_url_scanner_ex_deactivate(TSRMLS_C);
 1020: 		BG(url_adapt_state_ex).active = 0;
 1021: 	}
 1022: 
 1023: 	smart_str_free(&BG(url_adapt_state_ex).form_app);
 1024: 	smart_str_free(&BG(url_adapt_state_ex).url_app);
 1025: 
 1026: 	return SUCCESS;
 1027: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>