You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1106 lines
30 KiB

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