📄 url_scanner_ex.c
字号:
/* Generated by re2c 0.9.11 on Tue Feb 28 09:46:35 2006 *//* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Sascha Schumann <sascha@schumann.cx> | +----------------------------------------------------------------------+*//* $Id: url_scanner_ex.c,v 1.72.2.15.2.6 2007/01/01 09:46:48 sebastian Exp $ */#include "php.h"#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_LIMITS_H#include <limits.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include "php_ini.h"#include "php_globals.h"#define STATE_TAG SOME_OTHER_STATE_TAG#include "basic_functions.h"#include "url.h"#undef STATE_TAG#define url_scanner url_scanner_ex#include "php_smart_str.h"static PHP_INI_MH(OnUpdateTags){ url_adapt_state_ex_t *ctx; char *key; char *lasts; char *tmp; ctx = &BG(url_adapt_state_ex); tmp = estrndup(new_value, new_value_length); if (ctx->tags) zend_hash_destroy(ctx->tags); else ctx->tags = malloc(sizeof(HashTable)); zend_hash_init(ctx->tags, 0, NULL, NULL, 1); for (key = php_strtok_r(tmp, ",", &lasts); key; key = php_strtok_r(NULL, ",", &lasts)) { char *val; val = strchr(key, '='); if (val) { char *q; int keylen; *val++ = '\0'; for (q = key; *q; q++) *q = tolower(*q); keylen = q - key; /* key is stored withOUT NUL val is stored WITH NUL */ zend_hash_add(ctx->tags, key, keylen, val, strlen(val)+1, NULL); } } efree(tmp); return SUCCESS;}PHP_INI_BEGIN() 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)PHP_INI_END()#define YYFILL(n) goto done#define YYCTYPE unsigned char#define YYCURSOR p#define YYLIMIT q#define YYMARKER r static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator){ register const char *p, *q; const char *bash = NULL; const char *sep = "?"; q = (p = url->c) + url->len;scan:{ YYCTYPE yych; goto yy0; ++YYCURSOR;yy0: if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; switch(yych){ case '#': goto yy6; case ':': goto yy2; case '?': goto yy4; default: goto yy8; }yy2: ++YYCURSOR; goto yy3;yy3:{ smart_str_append(dest, url); return; }yy4: ++YYCURSOR; goto yy5;yy5:{ sep = separator; goto scan; }yy6: ++YYCURSOR; goto yy7;yy7:{ bash = p - 1; goto done; }yy8: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy9;yy9: switch(yych){ case '#': case ':': case '?': goto yy10; default: goto yy8; }yy10:{ goto scan; }}done: /* Don't modify URLs of the format "#mark" */ if (bash && bash - url->c == 0) { smart_str_append(dest, url); return; } if (bash) smart_str_appendl(dest, url->c, bash - url->c); else smart_str_append(dest, url); smart_str_appends(dest, sep); smart_str_append(dest, url_app); if (bash) smart_str_appendl(dest, bash, q - bash);}#undef YYFILL#undef YYCTYPE#undef YYCURSOR#undef YYLIMIT#undef YYMARKERstatic inline void tag_arg(url_adapt_state_ex_t *ctx, char quotes, char type TSRMLS_DC){ char f = 0; if (strncasecmp(ctx->arg.c, ctx->lookup_data, ctx->arg.len) == 0) f = 1; if (quotes) smart_str_appendc(&ctx->result, type); if (f) { append_modified_url(&ctx->val, &ctx->result, &ctx->url_app, PG(arg_separator).output); } else { smart_str_append(&ctx->result, &ctx->val); } if (quotes) smart_str_appendc(&ctx->result, type);}enum { STATE_PLAIN = 0, STATE_TAG, STATE_NEXT_ARG, STATE_ARG, STATE_BEFORE_VAL, STATE_VAL};#define YYFILL(n) goto stop#define YYCTYPE unsigned char#define YYCURSOR xp#define YYLIMIT end#define YYMARKER q#define STATE ctx->state#define STD_PARA url_adapt_state_ex_t *ctx, char *start, char *YYCURSOR TSRMLS_DC#define STD_ARGS ctx, start, xp TSRMLS_CC#if SCANNER_DEBUG#define scdebug(x) printf x#else#define scdebug(x)#endifstatic inline void passthru(STD_PARA) { scdebug(("appending %d chars, starting with %c\n", YYCURSOR-start, *start)); smart_str_appendl(&ctx->result, start, YYCURSOR - start);}/* * This function appends a hidden input field after a <form> or * <fieldset>. The latter is important for XHTML. */static void handle_form(STD_PARA) { int doit = 0; if (ctx->form_app.len > 0) { switch (ctx->tag.len) {#define RECOGNIZE(x) do { \ case sizeof(x)-1: \ if (strncasecmp(ctx->tag.c, x, sizeof(x)-1) == 0) \ doit = 1; \ break; \} while (0) RECOGNIZE("form"); RECOGNIZE("fieldset"); } if (doit) smart_str_append(&ctx->result, &ctx->form_app); }}/* * HANDLE_TAG copies the HTML Tag and checks whether we * have that tag in our table. If we might modify it, * we continue to scan the tag, otherwise we simply copy the complete * HTML stuff to the result buffer. */static inline void handle_tag(STD_PARA) { int ok = 0; int i; ctx->tag.len = 0; smart_str_appendl(&ctx->tag, start, YYCURSOR - start); for (i = 0; i < ctx->tag.len; i++) ctx->tag.c[i] = tolower((int)(unsigned char)ctx->tag.c[i]); if (zend_hash_find(ctx->tags, ctx->tag.c, ctx->tag.len, (void **) &ctx->lookup_data) == SUCCESS) ok = 1; STATE = ok ? STATE_NEXT_ARG : STATE_PLAIN;}static inline void handle_arg(STD_PARA) { ctx->arg.len = 0; smart_str_appendl(&ctx->arg, start, YYCURSOR - start);}static inline void handle_val(STD_PARA, char quotes, char type) { smart_str_setl(&ctx->val, start + quotes, YYCURSOR - start - quotes * 2); tag_arg(ctx, quotes, type TSRMLS_CC);}static inline void xx_mainloop(url_adapt_state_ex_t *ctx, const char *newdata, size_t newlen TSRMLS_DC){ char *end, *q; char *xp; char *start; int rest; smart_str_appendl(&ctx->buf, newdata, newlen); YYCURSOR = ctx->buf.c; YYLIMIT = ctx->buf.c + ctx->buf.len; switch (STATE) { case STATE_PLAIN: goto state_plain; case STATE_TAG: goto state_tag; case STATE_NEXT_ARG: goto state_next_arg; case STATE_ARG: goto state_arg; case STATE_BEFORE_VAL: goto state_before_val; case STATE_VAL: goto state_val; } state_plain_begin: STATE = STATE_PLAIN; state_plain: start = YYCURSOR;{ YYCTYPE yych; goto yy11; ++YYCURSOR;yy11: if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; switch(yych){ case '<': goto yy13; default: goto yy15; }yy13: ++YYCURSOR; goto yy14;yy14:{ passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }yy15: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy16;yy16: switch(yych){ case '<': goto yy17; default: goto yy15; }yy17:{ passthru(STD_ARGS); goto state_plain; }}state_tag: start = YYCURSOR;{ YYCTYPE yych; goto yy18; ++YYCURSOR;yy18: if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; switch(yych){ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': goto yy20; default: goto yy22; }yy20: ++YYCURSOR; yych = *YYCURSOR; goto yy25;yy21:{ handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; }yy22: ++YYCURSOR; goto yy23;yy23:{ passthru(STD_ARGS); goto state_plain_begin; }yy24: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy25;yy25: switch(yych){ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': goto yy24; default: goto yy21; }}state_next_arg_begin: STATE = STATE_NEXT_ARG; state_next_arg: start = YYCURSOR;{ YYCTYPE yych; goto yy26; ++YYCURSOR;yy26: if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; switch(yych){ case 0x09: case 0x0A: case 0x0B: case 0x0D: case ' ': goto yy30; case '>': goto yy28; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -