]> granicus.if.org Git - php/commitdiff
Cleanup trans sid code. Behavior is unchanged.
authorYasuo Ohgaki <yohgaki@php.net>
Mon, 2 Feb 2015 03:53:41 +0000 (12:53 +0900)
committerYasuo Ohgaki <yohgaki@php.net>
Mon, 2 Feb 2015 08:06:16 +0000 (17:06 +0900)
Fixed possible injections. Escape values usually internal safe values.

ext/session/php_session.h
ext/session/session.c
ext/session/tests/session_basic3.phpt [new file with mode: 0644]
ext/standard/url_scanner_ex.c
ext/standard/url_scanner_ex.h
ext/standard/url_scanner_ex.re

index c5750066fd5c80eccbc011b249f52d2cd8c07db4..2c3e0cf79868b0123145e0ba408ef8caa835aef1 100644 (file)
@@ -186,8 +186,7 @@ typedef struct _php_ps_globals {
        zend_bool auto_start;
        zend_bool use_cookies;
        zend_bool use_only_cookies;
-       zend_bool use_trans_sid;        /* contains the INI value of whether to use trans-sid */
-       zend_bool apply_trans_sid;      /* whether or not to enable trans-sid for the current request */
+       zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
 
        zend_long hash_func;
 #if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
index 966e0a6896f8ed86c1542ce6e86dd06cb9867fa3..010de352b91b99940707144d3f0df21470410ccb 100644 (file)
@@ -93,6 +93,8 @@ zend_class_entry *php_session_update_timestamp_iface_entry;
                return FAILURE; \
        }
 
+#define APPLY_TRANS_SID (PS(use_trans_sid) && !PS(use_only_cookies))
+
 static void php_session_send_cookie(void);
 
 /* Dispatched by RINIT and by php_session_destroy */
@@ -535,13 +537,6 @@ static void php_session_initialize(void) /* {{{ */
                php_session_decode(val);
                zend_string_release(val);
        }
-
-       if (!PS(use_cookies) && PS(send_cookie)) {
-               if (PS(use_trans_sid) && !PS(use_only_cookies)) {
-                       PS(apply_trans_sid) = 1;
-               }
-               PS(send_cookie) = 0;
-       }
 }
 /* }}} */
 
@@ -1463,7 +1458,7 @@ PHPAPI void php_session_reset_id(void) /* {{{ */
                PS(send_cookie) = 0;
        }
 
-       /* if the SID constant exists, destroy it. */
+       /* If the SID constant exists, destroy it. */
        /* We must not delete any items in EG(zend_contants) */
        /* zend_hash_str_del(EG(zend_constants), "sid", sizeof("sid") - 1); */
        sid = zend_get_constant_str("SID", sizeof("SID") - 1);
@@ -1491,8 +1486,8 @@ PHPAPI void php_session_reset_id(void) /* {{{ */
                }
        }
 
-       if (PS(apply_trans_sid)) {
-               php_url_scanner_reset_vars();
+       if (APPLY_TRANS_SID) {
+               /* php_url_scanner_reset_vars(); */
                php_url_scanner_add_var(PS(session_name), strlen(PS(session_name)), PS(id)->val, PS(id)->len, 1);
        }
 }
@@ -1506,12 +1501,6 @@ PHPAPI void php_session_start(void) /* {{{ */
        int nrand;
        size_t lensess;
 
-       if (PS(use_only_cookies)) {
-               PS(apply_trans_sid) = 0;
-       } else {
-               PS(apply_trans_sid) = PS(use_trans_sid);
-       }
-
        switch (PS(session_status)) {
                case php_session_active:
                        php_error(E_NOTICE, "A session had already been started - ignoring session_start()");
@@ -1540,14 +1529,20 @@ PHPAPI void php_session_start(void) /* {{{ */
 
                default:
                case php_session_none:
-                       PS(define_sid) = 1;
-                       PS(send_cookie) = 1;
+                       /* Setup internal flags */
+                       PS(define_sid) = !PS(use_only_cookies); /* SID constant is defined when non-cookie ID is used */
+                       PS(send_cookie) = PS(use_cookies) || PS(use_only_cookies);
        }
 
        lensess = strlen(PS(session_name));
 
-       /* Cookies are preferred, because initially
-        * cookie and get variables will be available. */
+       /*
+        * Cookies are preferred, because initially cookie and get
+        * variables will be available.
+        * URL/POST session ID may be used when use_only_cookies=Off.
+        * session.use_strice_mode=On prevents session adoption.
+        * Session based file upload progress uses non-cookie ID.
+        */
 
        if (!PS(id)) {
                if (PS(use_cookies) && (data = zend_hash_str_find(&EG(symbol_table).ht, "_COOKIE", sizeof("_COOKIE") - 1)) &&
@@ -1555,11 +1550,10 @@ PHPAPI void php_session_start(void) /* {{{ */
                                (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))
                ) {
                        ppid2sid(ppid);
-                       PS(apply_trans_sid) = 0;
-                       PS(define_sid) = 0;
+                       PS(send_cookie) = 0;
                }
 
-               if (!PS(use_only_cookies) && !PS(id) &&
+               if (PS(define_sid) && !PS(id) &&
                                (data = zend_hash_str_find(&EG(symbol_table).ht, "_GET", sizeof("_GET") - 1)) &&
                                Z_TYPE_P(data) == IS_ARRAY &&
                                (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))
@@ -1567,50 +1561,42 @@ PHPAPI void php_session_start(void) /* {{{ */
                        ppid2sid(ppid);
                }
 
-               if (!PS(use_only_cookies) && !PS(id) &&
+               if (PS(define_sid) && !PS(id) &&
                                (data = zend_hash_str_find(&EG(symbol_table).ht, "_POST", sizeof("_POST") - 1)) &&
                                Z_TYPE_P(data) == IS_ARRAY &&
                                (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))
                ) {
                        ppid2sid(ppid);
                }
-       }
-
-       /* Check the REQUEST_URI symbol for a string of the form
-        * '<session-name>=<session-id>' to allow URLs of the form
-        * http://yoursite/<session-name>=<session-id>/script.php */
 
-       if (!PS(use_only_cookies) && !PS(id) && !Z_ISUNDEF(PG(http_globals)[TRACK_VARS_SERVER]) &&
+               /* Check the REQUEST_URI symbol for a string of the form
+                * '<session-name>=<session-id>' to allow URLs of the form
+                * http://yoursite/<session-name>=<session-id>/script.php */
+               if (PS(define_sid) && !PS(id) &&
                        (data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "REQUEST_URI", sizeof("REQUEST_URI") - 1)) &&
                        Z_TYPE_P(data) == IS_STRING &&
                        (p = strstr(Z_STRVAL_P(data), PS(session_name))) &&
                        p[lensess] == '='
-       ) {
-               char *q;
-
-               p += lensess + 1;
-               if ((q = strpbrk(p, "/?\\"))) {
-                       PS(id) = zend_string_init(p, q - p, 0);
-                       PS(send_cookie) = 0;
+               ) {
+                       char *q;
+                       p += lensess + 1;
+                       if ((q = strpbrk(p, "/?\\"))) {
+                               PS(id) = zend_string_init(p, q - p, 0);
+                       }
                }
-       }
-
-       /* Check whether the current request was referred to by
-        * an external site which invalidates the previously found id. */
 
-       if (PS(id) &&
+               /* Check whether the current request was referred to by
+                * an external site which invalidates the previously found id. */
+               if (PS(define_sid) && PS(id) &&
                        PS(extern_referer_chk)[0] != '\0' &&
                        !Z_ISUNDEF(PG(http_globals)[TRACK_VARS_SERVER]) &&
                        (data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_REFERER", sizeof("HTTP_REFERER") - 1)) &&
                        Z_TYPE_P(data) == IS_STRING &&
                        Z_STRLEN_P(data) != 0 &&
                        strstr(Z_STRVAL_P(data), PS(extern_referer_chk)) == NULL
-       ) {
-               zend_string_release(PS(id));
-               PS(id) = NULL;
-               PS(send_cookie) = 1;
-               if (PS(use_trans_sid) && !PS(use_only_cookies)) {
-                       PS(apply_trans_sid) = 1;
+               ) {
+                       zend_string_release(PS(id));
+                       PS(id) = NULL;
                }
        }
 
@@ -1669,10 +1655,13 @@ static void php_session_reset(void) /* {{{ */
 /* }}} */
 
 
+/* This API is not used by any PHP modules including session currently.
+   session_adapt_url() may be used to set Session ID to target url without
+   starting "URL-Rewriter" output handler. */
 PHPAPI void session_adapt_url(const char *url, size_t urllen, char **new, size_t *newlen) /* {{{ */
 {
-       if (PS(apply_trans_sid) && (PS(session_status) == php_session_active)) {
-               *new = php_url_scanner_adapt_single_url(url, urllen, PS(session_name), PS(id)->val, newlen);
+       if (APPLY_TRANS_SID && (PS(session_status) == php_session_active)) {
+               *new = php_url_scanner_adapt_single_url(url, urllen, PS(session_name), PS(id)->val, newlen, 1);
        }
 }
 /* }}} */
@@ -2872,7 +2861,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
                                        smart_str_appendl(&progress->key, *data->value, value_len);
                                        smart_str_0(&progress->key);
 
-                                       progress->apply_trans_sid = PS(use_trans_sid);
+                                       progress->apply_trans_sid = APPLY_TRANS_SID;
                                        php_session_rfc1867_early_find_sid(progress);
                                }
                        }
@@ -2911,7 +2900,11 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
 
                                php_rinit_session(0);
                                PS(id) = zend_string_init(Z_STRVAL(progress->sid), Z_STRLEN(progress->sid), 0);
-                               PS(apply_trans_sid) = progress->apply_trans_sid;
+                               if (progress->apply_trans_sid) {
+                                       /* Enable trans sid by modifying flags */
+                                       PS(use_trans_sid) = 1;
+                                       PS(use_only_cookies) = 0;
+                               }
                                PS(send_cookie) = 0;
                        }
 
diff --git a/ext/session/tests/session_basic3.phpt b/ext/session/tests/session_basic3.phpt
new file mode 100644 (file)
index 0000000..08e3aae
--- /dev/null
@@ -0,0 +1,248 @@
+--TEST--
+Test basic function : variation3 use_trans_sid
+--INI--
+session.use_strict_mode=0
+session.use_only_cookies=0
+session.use_trans_sid=1
+session.save_handler=files
+session.hash_bits_per_character=4
+session.hash_function=0
+session.gc_probability=1
+session.gc_divisor=1000
+session.gc_maxlifetime=300
+session.save_path=
+session.name=PHPSESSID
+--XFAIL--
+Waiting url_scanner_ex.re fix. https://bugs.php.net/bug.php?id=68970
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : session.use_trans_sid=1
+ * Description : Test basic functionality.
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing basic session functionality : variation3 use_trans_sid ***\n";
+
+/*
+echo "*** test output_add_rewrite_var() ***\n";
+output_add_rewrite_var('var', 'value');
+echo '
+<a href="/">test</a>
+<a href="/#bar">test</a>
+<a href="/?foo">test</a>
+<a href="/?foo#bar">test</a>
+<a href="/?foo=var">test</a>
+<a href="/?foo=var#bar">test</a>
+<a href="file.php">test</a>
+<a href="file.php?foo">test</a>
+<a href="file.php?foo=var">test</a>
+<a href="http://php.net">test</a>
+<a href="http://php.net/">test</a>
+<a href="http://php.net/#bar">test</a>
+<a href="http://php.net/?foo">test</a>
+<a href="http://php.net/?foo#bar">test</a>
+<a href="http://php.net/?foo=var">test</a>
+<a href="http://php.net/?foo=var#bar">test</a>
+<a href="http://php.net/file.php">test</a>
+<a href="http://php.net/file.php#bar">test</a>
+<a href="http://php.net/file.php?foo">test</a>
+<a href="http://php.net/file.php?foo#bar">test</a>
+<a href="http://php.net/file.php?foo=var">test</a>
+<a href="http://php.net/file.php?foo=var#bar">test</a>
+<a href="http://php.net/some/path/file.php">test</a>
+<a href="http://php.net/some/path/file.php?foo">test</a>
+<a href="http://php.net/some/path/file.php?foo=var">test</a>
+<a href="http://php.net/some/path/file.php?foo=var#bar">test</a>
+<a href="https://php.net">test</a>
+<a href="https://php.net/">test</a>
+<a href="https://php.net/?foo=var#bar">test</a>
+<a href="https://php.net/file.php">test</a>
+<a href="https://php.net/file.php?foo=var#bar">test</a>
+<a href="https://php.net/some/path/file.php">test</a>
+<a href="https://php.net/some/path/file.php?foo=var#bar">test</a>
+<a href="https://php.net:8443">test</a>
+<a href="https://php.net:8443/">test</a>
+<a href="https://php.net:8443/?foo=var#bar">test</a>
+<a href="https://php.net:8443/file.php">test</a>
+<a href="https://php.net:8443/file.php?foo=var#bar">test</a>
+<a href="https://php.net:8443/some/path/file.php">test</a>
+<a href="https://php.net:8443/some/path/file.php?foo=var#bar">test</a>
+<a href="//php.net">test</a>
+<a href="//php.net/">test</a>
+<a href="//php.net/#bar">test</a>
+<a href="//php.net/?foo">test</a>
+<a href="//php.net/?foo#bar">test</a>
+<a href="//php.net/?foo=var">test</a>
+<a href="//php.net/?foo=var#bar">test</a>
+<a href="//php.net/file.php">test</a>
+<a href="//php.net/file.php#bar">test</a>
+<a href="//php.net/file.php?foo">test</a>
+<a href="//php.net/file.php?foo#bar">test</a>
+<a href="//php.net/file.php?foo=var">test</a>
+<a href="//php.net/file.php?foo=var#bar">test</a>
+<a href="//php.net/some/path/file.php">test</a>
+<a href="//php.net/some/path/file.php?foo">test</a>
+<a href="//php.net/some/path/file.php?foo=var">test</a>
+<a href="//php.net/some/path/file.php?foo=var#bar">test</a>
+<form action="script.php" method="post">
+  <input type="text" name="test1"></input>
+  <input type="text" name="test2" />
+</form>
+';
+output_reset_rewrite_vars();
+*/
+
+echo "*** Test trans sid ***\n";
+ob_start();
+$session_id = 'testid';
+session_id($session_id);
+session_start();
+// Should add session ID to relative URL only for SECURITY
+echo '
+<a href="/">test</a>
+<a href="/#bar">test</a>
+<a href="/?foo">test</a>
+<a href="/?foo#bar">test</a>
+<a href="/?foo=var">test</a>
+<a href="/?foo=var#bar">test</a>
+<a href="file.php">test</a>
+<a href="file.php?foo">test</a>
+<a href="file.php?foo=var">test</a>
+<a href="http://php.net">test</a>
+<a href="http://php.net/">test</a>
+<a href="http://php.net/#bar">test</a>
+<a href="http://php.net/?foo">test</a>
+<a href="http://php.net/?foo#bar">test</a>
+<a href="http://php.net/?foo=var">test</a>
+<a href="http://php.net/?foo=var#bar">test</a>
+<a href="http://php.net/file.php">test</a>
+<a href="http://php.net/file.php#bar">test</a>
+<a href="http://php.net/file.php?foo">test</a>
+<a href="http://php.net/file.php?foo#bar">test</a>
+<a href="http://php.net/file.php?foo=var">test</a>
+<a href="http://php.net/file.php?foo=var#bar">test</a>
+<a href="http://php.net/some/path/file.php">test</a>
+<a href="http://php.net/some/path/file.php?foo">test</a>
+<a href="http://php.net/some/path/file.php?foo=var">test</a>
+<a href="http://php.net/some/path/file.php?foo=var#bar">test</a>
+<a href="https://php.net">test</a>
+<a href="https://php.net/">test</a>
+<a href="https://php.net/?foo=var#bar">test</a>
+<a href="https://php.net/file.php">test</a>
+<a href="https://php.net/file.php?foo=var#bar">test</a>
+<a href="https://php.net/some/path/file.php">test</a>
+<a href="https://php.net/some/path/file.php?foo=var#bar">test</a>
+<a href="https://php.net:8443">test</a>
+<a href="https://php.net:8443/">test</a>
+<a href="https://php.net:8443/?foo=var#bar">test</a>
+<a href="https://php.net:8443/file.php">test</a>
+<a href="https://php.net:8443/file.php?foo=var#bar">test</a>
+<a href="https://php.net:8443/some/path/file.php">test</a>
+<a href="https://php.net:8443/some/path/file.php?foo=var#bar">test</a>
+<a href="//php.net">test</a>
+<a href="//php.net/">test</a>
+<a href="//php.net/#bar">test</a>
+<a href="//php.net/?foo">test</a>
+<a href="//php.net/?foo#bar">test</a>
+<a href="//php.net/?foo=var">test</a>
+<a href="//php.net/?foo=var#bar">test</a>
+<a href="//php.net/file.php">test</a>
+<a href="//php.net/file.php#bar">test</a>
+<a href="//php.net/file.php?foo">test</a>
+<a href="//php.net/file.php?foo#bar">test</a>
+<a href="//php.net/file.php?foo=var">test</a>
+<a href="//php.net/file.php?foo=var#bar">test</a>
+<a href="//php.net/some/path/file.php">test</a>
+<a href="//php.net/some/path/file.php?foo">test</a>
+<a href="//php.net/some/path/file.php?foo=var">test</a>
+<a href="//php.net/some/path/file.php?foo=var#bar">test</a>
+<form action="script.php" method="post">
+  <input type="text" name="test1"></input>
+  <input type="text" name="test2" />
+</form>
+';
+var_dump(session_commit());
+
+echo "*** Cleanup ***\n";
+var_dump(session_start());
+var_dump(session_id());
+var_dump(session_destroy());
+
+ob_end_flush();
+?>
+--EXPECT--
+*** Testing basic session functionality : variation3 use_trans_sid ***
+*** Test trans sid ***
+
+<a href="/?PHPSESSID=testid&PHPSESSID=testid">test</a>
+<a href="/?PHPSESSID=testid&PHPSESSID=testid#bar">test</a>
+<a href="/?foo&PHPSESSID=testid&PHPSESSID=testid">test</a>
+<a href="/?foo&PHPSESSID=testid&PHPSESSID=testid#bar">test</a>
+<a href="/?foo=var&PHPSESSID=testid&PHPSESSID=testid">test</a>
+<a href="/?foo=var&PHPSESSID=testid&PHPSESSID=testid#bar">test</a>
+<a href="file.php?PHPSESSID=testid&PHPSESSID=testid">test</a>
+<a href="file.php?foo&PHPSESSID=testid&PHPSESSID=testid">test</a>
+<a href="file.php?foo=var&PHPSESSID=testid&PHPSESSID=testid">test</a>
+<a href="http://php.net">test</a>
+<a href="http://php.net/">test</a>
+<a href="http://php.net/#bar">test</a>
+<a href="http://php.net/?foo">test</a>
+<a href="http://php.net/?foo#bar">test</a>
+<a href="http://php.net/?foo=var">test</a>
+<a href="http://php.net/?foo=var#bar">test</a>
+<a href="http://php.net/file.php">test</a>
+<a href="http://php.net/file.php#bar">test</a>
+<a href="http://php.net/file.php?foo">test</a>
+<a href="http://php.net/file.php?foo#bar">test</a>
+<a href="http://php.net/file.php?foo=var">test</a>
+<a href="http://php.net/file.php?foo=var#bar">test</a>
+<a href="http://php.net/some/path/file.php">test</a>
+<a href="http://php.net/some/path/file.php?foo">test</a>
+<a href="http://php.net/some/path/file.php?foo=var">test</a>
+<a href="http://php.net/some/path/file.php?foo=var#bar">test</a>
+<a href="https://php.net">test</a>
+<a href="https://php.net/">test</a>
+<a href="https://php.net/?foo=var#bar">test</a>
+<a href="https://php.net/file.php">test</a>
+<a href="https://php.net/file.php?foo=var#bar">test</a>
+<a href="https://php.net/some/path/file.php">test</a>
+<a href="https://php.net/some/path/file.php?foo=var#bar">test</a>
+<a href="https://php.net:8443">test</a>
+<a href="https://php.net:8443/">test</a>
+<a href="https://php.net:8443/?foo=var#bar">test</a>
+<a href="https://php.net:8443/file.php">test</a>
+<a href="https://php.net:8443/file.php?foo=var#bar">test</a>
+<a href="https://php.net:8443/some/path/file.php">test</a>
+<a href="https://php.net:8443/some/path/file.php?foo=var#bar">test</a>
+<a href="//php.net">test</a>
+<a href="//php.net/">test</a>
+<a href="//php.net/#bar">test</a>
+<a href="//php.net/?foo">test</a>
+<a href="//php.net/?foo#bar">test</a>
+<a href="//php.net/?foo=var">test</a>
+<a href="//php.net/?foo=var#bar">test</a>
+<a href="//php.net/file.php">test</a>
+<a href="//php.net/file.php#bar">test</a>
+<a href="//php.net/file.php?foo">test</a>
+<a href="//php.net/file.php?foo#bar">test</a>
+<a href="//php.net/file.php?foo=var">test</a>
+<a href="//php.net/file.php?foo=var#bar">test</a>
+<a href="//php.net/some/path/file.php">test</a>
+<a href="//php.net/some/path/file.php?foo">test</a>
+<a href="//php.net/some/path/file.php?foo=var">test</a>
+<a href="//php.net/some/path/file.php?foo=var#bar">test</a>
+<form action="script.php" method="post"><input type="hidden" name="PHPSESSID" value="testid" /><input type="hidden" name="PHPSESSID" value="testid" />
+  <input type="text" name="test1"></input>
+  <input type="text" name="test2" />
+</form>
+NULL
+*** Cleanup ***
+bool(true)
+string(6) "testid"
+bool(true)
\ No newline at end of file
index 5b9bbd57ae4ed0b091449b28d827374541748845..0014027872a9e0f37b0f36dae5e1727b73373080 100644 (file)
@@ -123,38 +123,38 @@ scan:
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128,   0, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128,   0, 128, 128, 128, 128,   0,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128,   0, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128,   0, 128, 128, 128, 128,   0, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
        };
 
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -378,38 +378,38 @@ state_plain:
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128,   0, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128,   0, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
        };
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
@@ -441,38 +441,38 @@ state_tag:
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0, 128,   0,   0,   0,   0,   0,
-                 0, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128,   0,   0,   0,   0,   0,
-                 0, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0, 128,   0,   0,   0,   0,   0, 
+                 0, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128,   0,   0,   0,   0,   0, 
+                 0, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
        };
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
@@ -519,38 +519,38 @@ state_next_arg:
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0, 128, 128, 128,   0, 128,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-               128,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0, 128, 128, 128,   0, 128,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+               128,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
        };
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
@@ -629,38 +629,38 @@ state_arg:
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0, 128,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128,   0,   0,   0,   0,   0,
-                 0, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128, 128, 128, 128, 128, 128,
-               128, 128, 128,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0, 128,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128,   0,   0,   0,   0,   0, 
+                 0, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128, 
+               128, 128, 128,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
        };
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
@@ -701,38 +701,38 @@ state_before_val:
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-               128,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
-                 0,   0,   0,   0,   0,   0,   0,   0,
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+               128,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
+                 0,   0,   0,   0,   0,   0,   0,   0, 
        };
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
@@ -787,38 +787,38 @@ state_val:
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 192, 192, 224, 224, 192, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               192, 224,  64, 224, 224, 224, 224, 128,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224,   0, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
-               224, 224, 224, 224, 224, 224, 224, 224,
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 192, 192, 224, 224, 192, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               192, 224,  64, 224, 224, 224, 224, 128, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224,   0, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
+               224, 224, 224, 224, 224, 224, 224, 224, 
        };
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
@@ -918,18 +918,32 @@ stop:
        ctx->buf.s->len = rest;
 }
 
-char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen)
+
+PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen, int urlencode)
 {
        char *result;
        smart_str surl = {0};
        smart_str buf = {0};
        smart_str url_app = {0};
+       zend_string *encoded;
 
-       smart_str_setl(&surl, url, urllen);
+       smart_str_appendl(&surl, url, urllen);
 
-       smart_str_appends(&url_app, name);
+       if (urlencode) {
+               encoded = php_raw_url_encode(name, strlen(name));
+               smart_str_appendl(&url_app, encoded->val, encoded->len);
+               zend_string_free(encoded);
+       } else {
+               smart_str_appends(&url_app, name);
+       }
        smart_str_appendc(&url_app, '=');
-       smart_str_appends(&url_app, value);
+       if (urlencode) {
+               encoded = php_raw_url_encode(value, strlen(value));
+               smart_str_appendl(&url_app, encoded->val, encoded->len);
+               zend_string_free(encoded);
+       } else {
+               smart_str_appends(&url_app, value);
+       }
 
        append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output);
 
@@ -1028,7 +1042,8 @@ static void php_url_scanner_output_handler(char *output, size_t output_len, char
 
 PHPAPI int php_url_scanner_add_var(char *name, size_t name_len, char *value, size_t value_len, int urlencode)
 {
-       smart_str val = {0};
+       smart_str sname = {0};
+       smart_str svalue = {0};
        zend_string *encoded;
 
        if (!BG(url_adapt_state_ex).active) {
@@ -1037,32 +1052,34 @@ PHPAPI int php_url_scanner_add_var(char *name, size_t name_len, char *value, siz
                BG(url_adapt_state_ex).active = 1;
        }
 
-
        if (BG(url_adapt_state_ex).url_app.s && BG(url_adapt_state_ex).url_app.s->len != 0) {
                smart_str_appends(&BG(url_adapt_state_ex).url_app, PG(arg_separator).output);
        }
 
        if (urlencode) {
-               encoded = php_url_encode(value, value_len);
-               smart_str_setl(&val, encoded->val, encoded->len);
+               encoded = php_raw_url_encode(name, name_len);
+               smart_str_appendl(&sname, encoded->val, encoded->len);
+               zend_string_free(encoded);
+               encoded = php_raw_url_encode(value, value_len);
+               smart_str_appendl(&svalue, encoded->val, encoded->len);
+               zend_string_free(encoded);
        } else {
-               smart_str_setl(&val, value, value_len);
+               smart_str_appendl(&sname, name, name_len);
+               smart_str_appendl(&svalue, value, value_len);
        }
 
-       smart_str_appendl(&BG(url_adapt_state_ex).url_app, name, name_len);
+       smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &sname);
        smart_str_appendc(&BG(url_adapt_state_ex).url_app, '=');
-       smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &val);
+       smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &svalue);
 
        smart_str_appends(&BG(url_adapt_state_ex).form_app, "<input type=\"hidden\" name=\"");
-       smart_str_appendl(&BG(url_adapt_state_ex).form_app, name, name_len);
+       smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &sname);
        smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" value=\"");
-       smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &val);
+       smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &svalue);
        smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" />");
 
-       if (urlencode) {
-               zend_string_free(encoded);
-       }
-       smart_str_free(&val);
+       smart_str_free(&sname);
+       smart_str_free(&svalue);
 
        return SUCCESS;
 }
index 43902c14c06a46e1e60ef8b51459eac9eceb7566..a69a3257fa2fea94b04b0273987dab14fc0b2750 100644 (file)
@@ -27,7 +27,7 @@ PHP_MSHUTDOWN_FUNCTION(url_scanner_ex);
 PHP_RINIT_FUNCTION(url_scanner_ex);
 PHP_RSHUTDOWN_FUNCTION(url_scanner_ex);
 
-PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen);
+PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen, int urlencode);
 PHPAPI int php_url_scanner_add_var(char *name, size_t name_len, char *value, size_t value_len, int urlencode);
 PHPAPI int php_url_scanner_reset_vars(void);
 
index bb1d1e6cb6c7bd0bc8ab1de2e647e9ed8b57a710..48a6d8db62a08c38e8b34cf7524a3fcc27976ea2 100644 (file)
@@ -370,18 +370,32 @@ stop:
        ctx->buf.s->len = rest;
 }
 
-char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen)
+
+PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen, int urlencode)
 {
        char *result;
        smart_str surl = {0};
        smart_str buf = {0};
        smart_str url_app = {0};
+       zend_string *encoded;
 
-       smart_str_setl(&surl, url, urllen);
+       smart_str_appendl(&surl, url, urllen);
 
-       smart_str_appends(&url_app, name);
+       if (urlencode) {
+               encoded = php_raw_url_encode(name, strlen(name));
+               smart_str_appendl(&url_app, encoded->val, encoded->len);
+               zend_string_free(encoded);
+       } else {
+               smart_str_appends(&url_app, name);
+       }
        smart_str_appendc(&url_app, '=');
-       smart_str_appends(&url_app, value);
+       if (urlencode) {
+               encoded = php_raw_url_encode(value, strlen(value));
+               smart_str_appendl(&url_app, encoded->val, encoded->len);
+               zend_string_free(encoded);
+       } else {
+               smart_str_appends(&url_app, value);
+       }
 
        append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output);
 
@@ -480,7 +494,8 @@ static void php_url_scanner_output_handler(char *output, size_t output_len, char
 
 PHPAPI int php_url_scanner_add_var(char *name, size_t name_len, char *value, size_t value_len, int urlencode)
 {
-       smart_str val = {0};
+       smart_str sname = {0};
+       smart_str svalue = {0};
        zend_string *encoded;
 
        if (!BG(url_adapt_state_ex).active) {
@@ -489,32 +504,34 @@ PHPAPI int php_url_scanner_add_var(char *name, size_t name_len, char *value, siz
                BG(url_adapt_state_ex).active = 1;
        }
 
-
        if (BG(url_adapt_state_ex).url_app.s && BG(url_adapt_state_ex).url_app.s->len != 0) {
                smart_str_appends(&BG(url_adapt_state_ex).url_app, PG(arg_separator).output);
        }
 
        if (urlencode) {
-               encoded = php_url_encode(value, value_len);
-               smart_str_setl(&val, encoded->val, encoded->len);
+               encoded = php_raw_url_encode(name, name_len);
+               smart_str_appendl(&sname, encoded->val, encoded->len);
+               zend_string_free(encoded);
+               encoded = php_raw_url_encode(value, value_len);
+               smart_str_appendl(&svalue, encoded->val, encoded->len);
+               zend_string_free(encoded);
        } else {
-               smart_str_setl(&val, value, value_len);
+               smart_str_appendl(&sname, name, name_len);
+               smart_str_appendl(&svalue, value, value_len);
        }
 
-       smart_str_appendl(&BG(url_adapt_state_ex).url_app, name, name_len);
+       smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &sname);
        smart_str_appendc(&BG(url_adapt_state_ex).url_app, '=');
-       smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &val);
+       smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &svalue);
 
        smart_str_appends(&BG(url_adapt_state_ex).form_app, "<input type=\"hidden\" name=\"");
-       smart_str_appendl(&BG(url_adapt_state_ex).form_app, name, name_len);
+       smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &sname);
        smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" value=\"");
-       smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &val);
+       smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &svalue);
        smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" />");
 
-       if (urlencode) {
-               zend_string_free(encoded);
-       }
-       smart_str_free(&val);
+       smart_str_free(&sname);
+       smart_str_free(&svalue);
 
        return SUCCESS;
 }