PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - lcov_data/Zend - zend_language_scanner.l (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 965 1117 86.4 %
Date: 2014-10-16 Functions: 25 27 92.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Marcus Boerger <helly@php.net>                              |
      16             :    |          Nuno Lopes <nlopess@php.net>                                |
      17             :    |          Scott MacVicar <scottmac@php.net>                           |
      18             :    | Flex version authors:                                                |
      19             :    |          Andi Gutmans <andi@zend.com>                                |
      20             :    |          Zeev Suraski <zeev@zend.com>                                |
      21             :    +----------------------------------------------------------------------+
      22             : */
      23             : 
      24             : /* $Id$ */
      25             : 
      26             : #if 0
      27             : # define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c)
      28             : #else
      29             : # define YYDEBUG(s, c)
      30             : #endif
      31             : 
      32             : #include "zend_language_scanner_defs.h"
      33             : 
      34             : #include <errno.h>
      35             : #include "zend.h"
      36             : #ifdef PHP_WIN32
      37             : # include <Winuser.h>
      38             : #endif
      39             : #include "zend_alloc.h"
      40             : #include <zend_language_parser.h>
      41             : #include "zend_compile.h"
      42             : #include "zend_language_scanner.h"
      43             : #include "zend_highlight.h"
      44             : #include "zend_constants.h"
      45             : #include "zend_variables.h"
      46             : #include "zend_operators.h"
      47             : #include "zend_API.h"
      48             : #include "zend_strtod.h"
      49             : #include "zend_exceptions.h"
      50             : #include "tsrm_virtual_cwd.h"
      51             : #include "tsrm_config_common.h"
      52             : 
      53             : #define YYCTYPE   unsigned char
      54             : #define YYFILL(n) { if ((YYCURSOR + n) >= (YYLIMIT + ZEND_MMAP_AHEAD)) { return 0; } }
      55             : #define YYCURSOR  SCNG(yy_cursor)
      56             : #define YYLIMIT   SCNG(yy_limit)
      57             : #define YYMARKER  SCNG(yy_marker)
      58             : 
      59             : #define YYGETCONDITION()  SCNG(yy_state)
      60             : #define YYSETCONDITION(s) SCNG(yy_state) = s
      61             : 
      62             : #define STATE(name)  yyc##name
      63             : 
      64             : /* emulate flex constructs */
      65             : #define BEGIN(state) YYSETCONDITION(STATE(state))
      66             : #define YYSTATE      YYGETCONDITION()
      67             : #define yytext       ((char*)SCNG(yy_text))
      68             : #define yyleng       SCNG(yy_leng)
      69             : #define yyless(x)    do { YYCURSOR = (unsigned char*)yytext + x; \
      70             :                           yyleng   = (unsigned int)x; } while(0)
      71             : #define yymore()     goto yymore_restart
      72             : 
      73             : /* perform sanity check. If this message is triggered you should
      74             :    increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */
      75             : /*!max:re2c */
      76             : #if ZEND_MMAP_AHEAD < YYMAXFILL
      77             : # error ZEND_MMAP_AHEAD should be greater than or equal to YYMAXFILL
      78             : #endif
      79             : 
      80             : #ifdef HAVE_STDARG_H
      81             : # include <stdarg.h>
      82             : #endif
      83             : 
      84             : #ifdef HAVE_UNISTD_H
      85             : # include <unistd.h>
      86             : #endif
      87             : 
      88             : /* Globals Macros */
      89             : #define SCNG    LANG_SCNG
      90             : #ifdef ZTS
      91             : ZEND_API ts_rsrc_id language_scanner_globals_id;
      92             : #else
      93             : ZEND_API zend_php_scanner_globals language_scanner_globals;
      94             : #endif
      95             : 
      96             : #define HANDLE_NEWLINES(s, l)                                                                                                   \
      97             : do {                                                                                                                                                    \
      98             :         char *p = (s), *boundary = p+(l);                                                                                       \
      99             :                                                                                                                                                                 \
     100             :         while (p<boundary) {                                                                                                         \
     101             :                 if (*p == '\n' || (*p == '\r' && (*(p+1) != '\n'))) {                                   \
     102             :                         CG(zend_lineno)++;                                                                                                      \
     103             :                 }                                                                                                                                               \
     104             :                 p++;                                                                                                                                    \
     105             :         }                                                                                                                                                       \
     106             : } while (0)
     107             : 
     108             : #define HANDLE_NEWLINE(c) \
     109             : { \
     110             :         if (c == '\n' || c == '\r') { \
     111             :                 CG(zend_lineno)++; \
     112             :         } \
     113             : }
     114             : 
     115             : /* To save initial string length after scanning to first variable, CG(doc_comment_len) can be reused */
     116             : #define SET_DOUBLE_QUOTES_SCANNED_LENGTH(len) CG(doc_comment_len) = (len)
     117             : #define GET_DOUBLE_QUOTES_SCANNED_LENGTH()    CG(doc_comment_len)
     118             : 
     119             : #define IS_LABEL_START(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || (c) == '_' || (c) >= 0x7F)
     120             : 
     121             : #define ZEND_IS_OCT(c)  ((c)>='0' && (c)<='7')
     122             : #define ZEND_IS_HEX(c)  (((c)>='0' && (c)<='9') || ((c)>='a' && (c)<='f') || ((c)>='A' && (c)<='F'))
     123             : 
     124             : BEGIN_EXTERN_C()
     125             : 
     126          26 : static size_t encoding_filter_script_to_internal(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
     127             : {
     128          26 :         const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
     129          26 :         assert(internal_encoding && zend_multibyte_check_lexer_compatibility(internal_encoding));
     130          26 :         return zend_multibyte_encoding_converter(to, to_length, from, from_length, internal_encoding, LANG_SCNG(script_encoding) TSRMLS_CC);
     131             : }
     132             : 
     133           4 : static size_t encoding_filter_script_to_intermediate(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
     134             : {
     135           4 :         return zend_multibyte_encoding_converter(to, to_length, from, from_length, zend_multibyte_encoding_utf8, LANG_SCNG(script_encoding) TSRMLS_CC);
     136             : }
     137             : 
     138          27 : static size_t encoding_filter_intermediate_to_script(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
     139             : {
     140          27 :         return zend_multibyte_encoding_converter(to, to_length, from, from_length,
     141             : LANG_SCNG(script_encoding), zend_multibyte_encoding_utf8 TSRMLS_CC);
     142             : }
     143             : 
     144           0 : static size_t encoding_filter_intermediate_to_internal(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
     145             : {
     146           0 :         const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
     147           0 :         assert(internal_encoding && zend_multibyte_check_lexer_compatibility(internal_encoding));
     148           0 :         return zend_multibyte_encoding_converter(to, to_length, from, from_length,
     149             : internal_encoding, zend_multibyte_encoding_utf8 TSRMLS_CC);
     150             : }
     151             : 
     152             : 
     153      182144 : static void _yy_push_state(int new_state TSRMLS_DC)
     154             : {
     155      182144 :         zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
     156      182144 :         YYSETCONDITION(new_state);
     157      182144 : }
     158             : 
     159             : #define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm)
     160             : 
     161      182057 : static void yy_pop_state(TSRMLS_D)
     162             : {
     163             :         int *stack_state;
     164      182057 :         zend_stack_top(&SCNG(state_stack), (void **) &stack_state);
     165      182057 :         YYSETCONDITION(*stack_state);
     166      182057 :         zend_stack_del_top(&SCNG(state_stack));
     167      182057 : }
     168             : 
     169       30798 : static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
     170             : {
     171       30798 :         YYCURSOR       = (YYCTYPE*)str;
     172       30798 :         YYLIMIT        = YYCURSOR + len;
     173       30798 :         if (!SCNG(yy_start)) {
     174        1154 :                 SCNG(yy_start) = YYCURSOR;
     175             :         }
     176       30798 : }
     177             : 
     178       20182 : void startup_scanner(TSRMLS_D)
     179             : {
     180       20182 :         CG(parse_error) = 0;
     181       20182 :         CG(heredoc) = NULL;
     182       20182 :         CG(heredoc_len) = 0;
     183       20182 :         CG(doc_comment) = NULL;
     184       20182 :         CG(doc_comment_len) = 0;
     185       20182 :         zend_stack_init(&SCNG(state_stack));
     186       20182 : }
     187             : 
     188       20220 : void shutdown_scanner(TSRMLS_D)
     189             : {
     190       20220 :         if (CG(heredoc)) {
     191           2 :                 efree(CG(heredoc));
     192           2 :                 CG(heredoc_len)=0;
     193             :         }
     194       20220 :         CG(parse_error) = 0;
     195       20220 :         zend_stack_destroy(&SCNG(state_stack));
     196       20220 :         RESET_DOC_COMMENT();
     197       20220 : }
     198             : 
     199       30824 : ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
     200             : {
     201       30824 :         lex_state->yy_leng   = SCNG(yy_leng);
     202       30824 :         lex_state->yy_start  = SCNG(yy_start);
     203       30824 :         lex_state->yy_text   = SCNG(yy_text);
     204       30824 :         lex_state->yy_cursor = SCNG(yy_cursor);
     205       30824 :         lex_state->yy_marker = SCNG(yy_marker);
     206       30824 :         lex_state->yy_limit  = SCNG(yy_limit);
     207             : 
     208       30824 :         lex_state->state_stack = SCNG(state_stack);
     209       30824 :         zend_stack_init(&SCNG(state_stack));
     210             : 
     211       30824 :         lex_state->in = SCNG(yy_in);
     212       30824 :         lex_state->yy_state = YYSTATE;
     213       30824 :         lex_state->filename = zend_get_compiled_filename(TSRMLS_C);
     214       30824 :         lex_state->lineno = CG(zend_lineno);
     215             : 
     216       30824 :         lex_state->script_org = SCNG(script_org);
     217       30824 :         lex_state->script_org_size = SCNG(script_org_size);
     218       30824 :         lex_state->script_filtered = SCNG(script_filtered);
     219       30824 :         lex_state->script_filtered_size = SCNG(script_filtered_size);
     220       30824 :         lex_state->input_filter = SCNG(input_filter);
     221       30824 :         lex_state->output_filter = SCNG(output_filter);
     222       30824 :         lex_state->script_encoding = SCNG(script_encoding);
     223       30824 : }
     224             : 
     225       30639 : ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
     226             : {
     227       30639 :         SCNG(yy_leng)   = lex_state->yy_leng;
     228       30639 :         SCNG(yy_start)  = lex_state->yy_start;
     229       30639 :         SCNG(yy_text)   = lex_state->yy_text;
     230       30639 :         SCNG(yy_cursor) = lex_state->yy_cursor;
     231       30639 :         SCNG(yy_marker) = lex_state->yy_marker;
     232       30639 :         SCNG(yy_limit)  = lex_state->yy_limit;
     233             : 
     234       30639 :         zend_stack_destroy(&SCNG(state_stack));
     235       30639 :         SCNG(state_stack) = lex_state->state_stack;
     236             : 
     237       30639 :         SCNG(yy_in) = lex_state->in;
     238       30639 :         YYSETCONDITION(lex_state->yy_state);
     239       30639 :         CG(zend_lineno) = lex_state->lineno;
     240       30639 :         zend_restore_compiled_filename(lex_state->filename TSRMLS_CC);
     241             : 
     242       30639 :         if (SCNG(script_filtered)) {
     243          16 :                 efree(SCNG(script_filtered));
     244          16 :                 SCNG(script_filtered) = NULL;
     245             :         }
     246       30639 :         SCNG(script_org) = lex_state->script_org;
     247       30639 :         SCNG(script_org_size) = lex_state->script_org_size;
     248       30639 :         SCNG(script_filtered) = lex_state->script_filtered;
     249       30639 :         SCNG(script_filtered_size) = lex_state->script_filtered_size;
     250       30639 :         SCNG(input_filter) = lex_state->input_filter;
     251       30639 :         SCNG(output_filter) = lex_state->output_filter;
     252       30639 :         SCNG(script_encoding) = lex_state->script_encoding;
     253             : 
     254       30639 :         if (CG(heredoc)) {
     255           1 :                 efree(CG(heredoc));
     256           1 :                 CG(heredoc) = NULL;
     257           1 :                 CG(heredoc_len) = 0;
     258             :         }
     259       30639 :         RESET_DOC_COMMENT();
     260       30639 : }
     261             : 
     262       29483 : ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC)
     263             : {
     264       29483 :         zend_llist_del_element(&CG(open_files), file_handle, (int (*)(void *, void *)) zend_compare_file_handles);
     265             :         /* zend_file_handle_dtor() operates on the copy, so we have to NULLify the original here */
     266       29483 :         file_handle->opened_path = NULL;
     267       29483 :         if (file_handle->free_filename) {
     268           0 :                 file_handle->filename = NULL;
     269             :         }
     270       29483 : }
     271             : 
     272             : #define BOM_UTF32_BE    "\x00\x00\xfe\xff"
     273             : #define BOM_UTF32_LE    "\xff\xfe\x00\x00"
     274             : #define BOM_UTF16_BE    "\xfe\xff"
     275             : #define BOM_UTF16_LE    "\xff\xfe"
     276             : #define BOM_UTF8                "\xef\xbb\xbf"
     277             : 
     278           0 : static const zend_encoding *zend_multibyte_detect_utf_encoding(const unsigned char *script, size_t script_size TSRMLS_DC)
     279             : {
     280             :         const unsigned char *p;
     281           0 :         int wchar_size = 2;
     282           0 :         int le = 0;
     283             : 
     284             :         /* utf-16 or utf-32? */
     285           0 :         p = script;
     286           0 :         while ((p-script) < script_size) {
     287           0 :                 p = memchr(p, 0, script_size-(p-script)-2);
     288           0 :                 if (!p) {
     289           0 :                         break;
     290             :                 }
     291           0 :                 if (*(p+1) == '\0' && *(p+2) == '\0') {
     292           0 :                         wchar_size = 4;
     293           0 :                         break;
     294             :                 }
     295             : 
     296             :                 /* searching for UTF-32 specific byte orders, so this will do */
     297           0 :                 p += 4;
     298             :         }
     299             : 
     300             :         /* BE or LE? */
     301           0 :         p = script;
     302           0 :         while ((p-script) < script_size) {
     303           0 :                 if (*p == '\0' && *(p+wchar_size-1) != '\0') {
     304             :                         /* BE */
     305           0 :                         le = 0;
     306           0 :                         break;
     307           0 :                 } else if (*p != '\0' && *(p+wchar_size-1) == '\0') {
     308             :                         /* LE* */
     309           0 :                         le = 1;
     310           0 :                         break;
     311             :                 }
     312           0 :                 p += wchar_size;
     313             :         }
     314             : 
     315           0 :         if (wchar_size == 2) {
     316           0 :                 return le ? zend_multibyte_encoding_utf16le : zend_multibyte_encoding_utf16be;
     317             :         } else {
     318           0 :                 return le ? zend_multibyte_encoding_utf32le : zend_multibyte_encoding_utf32be;
     319             :         }
     320             : 
     321             :         return NULL;
     322             : }
     323             : 
     324          28 : static const zend_encoding* zend_multibyte_detect_unicode(TSRMLS_D)
     325             : {
     326          28 :         const zend_encoding *script_encoding = NULL;
     327             :         int bom_size;
     328             :         unsigned char *pos1, *pos2;
     329             : 
     330          28 :         if (LANG_SCNG(script_org_size) < sizeof(BOM_UTF32_LE)-1) {
     331           0 :                 return NULL;
     332             :         }
     333             : 
     334             :         /* check out BOM */
     335          28 :         if (!memcmp(LANG_SCNG(script_org), BOM_UTF32_BE, sizeof(BOM_UTF32_BE)-1)) {
     336           0 :                 script_encoding = zend_multibyte_encoding_utf32be;
     337           0 :                 bom_size = sizeof(BOM_UTF32_BE)-1;
     338          28 :         } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF32_LE, sizeof(BOM_UTF32_LE)-1)) {
     339           0 :                 script_encoding = zend_multibyte_encoding_utf32le;
     340           0 :                 bom_size = sizeof(BOM_UTF32_LE)-1;
     341          28 :         } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF16_BE, sizeof(BOM_UTF16_BE)-1)) {
     342           0 :                 script_encoding = zend_multibyte_encoding_utf16be;
     343           0 :                 bom_size = sizeof(BOM_UTF16_BE)-1;
     344          28 :         } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF16_LE, sizeof(BOM_UTF16_LE)-1)) {
     345           1 :                 script_encoding = zend_multibyte_encoding_utf16le;
     346           1 :                 bom_size = sizeof(BOM_UTF16_LE)-1;
     347          27 :         } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF8, sizeof(BOM_UTF8)-1)) {
     348           1 :                 script_encoding = zend_multibyte_encoding_utf8;
     349           1 :                 bom_size = sizeof(BOM_UTF8)-1;
     350             :         }
     351             : 
     352          28 :         if (script_encoding) {
     353             :                 /* remove BOM */
     354           2 :                 LANG_SCNG(script_org) += bom_size;
     355           2 :                 LANG_SCNG(script_org_size) -= bom_size;
     356             : 
     357           2 :                 return script_encoding;
     358             :         }
     359             : 
     360             :         /* script contains NULL bytes -> auto-detection */
     361          26 :         if ((pos1 = memchr(LANG_SCNG(script_org), 0, LANG_SCNG(script_org_size)))) {
     362             :                 /* check if the NULL byte is after the __HALT_COMPILER(); */
     363           0 :                 pos2 = LANG_SCNG(script_org);
     364             : 
     365           0 :                 while (pos1 - pos2 >= sizeof("__HALT_COMPILER();")-1) {
     366           0 :                         pos2 = memchr(pos2, '_', pos1 - pos2);
     367           0 :                         if (!pos2) break;
     368           0 :                         pos2++;
     369           0 :                         if (strncasecmp((char*)pos2, "_HALT_COMPILER", sizeof("_HALT_COMPILER")-1) == 0) {
     370           0 :                                 pos2 += sizeof("_HALT_COMPILER")-1;
     371           0 :                                 while (*pos2 == ' '  ||
     372           0 :                                            *pos2 == '\t' ||
     373           0 :                                            *pos2 == '\r' ||
     374           0 :                                            *pos2 == '\n') {
     375           0 :                                         pos2++;
     376             :                                 }
     377           0 :                                 if (*pos2 == '(') {
     378           0 :                                         pos2++;
     379           0 :                                         while (*pos2 == ' '  ||
     380           0 :                                                    *pos2 == '\t' ||
     381           0 :                                                    *pos2 == '\r' ||
     382           0 :                                                    *pos2 == '\n') {
     383           0 :                                                 pos2++;
     384             :                                         }
     385           0 :                                         if (*pos2 == ')') {
     386           0 :                                                 pos2++;
     387           0 :                                                 while (*pos2 == ' '  ||
     388           0 :                                                            *pos2 == '\t' ||
     389           0 :                                                            *pos2 == '\r' ||
     390           0 :                                                            *pos2 == '\n') {
     391           0 :                                                         pos2++;
     392             :                                                 }
     393           0 :                                                 if (*pos2 == ';') {
     394           0 :                                                         return NULL;
     395             :                                                 }
     396             :                                         }
     397             :                                 }
     398             :                         }
     399             :                 }
     400             :                 /* make best effort if BOM is missing */
     401           0 :                 return zend_multibyte_detect_utf_encoding(LANG_SCNG(script_org), LANG_SCNG(script_org_size) TSRMLS_CC);
     402             :         }
     403             : 
     404          26 :         return NULL;
     405             : }
     406             : 
     407          28 : static const zend_encoding* zend_multibyte_find_script_encoding(TSRMLS_D)
     408             : {
     409             :         const zend_encoding *script_encoding;
     410             : 
     411          28 :         if (CG(detect_unicode)) {
     412             :                 /* check out bom(byte order mark) and see if containing wchars */
     413          28 :                 script_encoding = zend_multibyte_detect_unicode(TSRMLS_C);
     414          28 :                 if (script_encoding != NULL) {
     415             :                         /* bom or wchar detection is prior to 'script_encoding' option */
     416           2 :                         return script_encoding;
     417             :                 }
     418             :         }
     419             : 
     420             :         /* if no script_encoding specified, just leave alone */
     421          26 :         if (!CG(script_encoding_list) || !CG(script_encoding_list_size)) {
     422          13 :                 return NULL;
     423             :         }
     424             : 
     425             :         /* if multiple encodings specified, detect automagically */
     426          13 :         if (CG(script_encoding_list_size) > 1) {
     427           0 :                 return zend_multibyte_encoding_detector(LANG_SCNG(script_org), LANG_SCNG(script_org_size), CG(script_encoding_list), CG(script_encoding_list_size) TSRMLS_CC);
     428             :         }
     429             : 
     430          13 :         return CG(script_encoding_list)[0];
     431             : }
     432             : 
     433          39 : ZEND_API int zend_multibyte_set_filter(const zend_encoding *onetime_encoding TSRMLS_DC)
     434             : {
     435          39 :         const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
     436          39 :         const zend_encoding *script_encoding = onetime_encoding ? onetime_encoding: zend_multibyte_find_script_encoding(TSRMLS_C);
     437             : 
     438          39 :         if (!script_encoding) {
     439          13 :                 return FAILURE;
     440             :         }
     441             : 
     442             :         /* judge input/output filter */
     443          26 :         LANG_SCNG(script_encoding) = script_encoding;
     444          26 :         LANG_SCNG(input_filter) = NULL;
     445          26 :         LANG_SCNG(output_filter) = NULL;
     446             : 
     447          26 :         if (!internal_encoding || LANG_SCNG(script_encoding) == internal_encoding) {
     448           7 :                 if (!zend_multibyte_check_lexer_compatibility(LANG_SCNG(script_encoding))) {
     449             :                         /* and if not, work around w/ script_encoding -> utf-8 -> script_encoding conversion */
     450           4 :                         LANG_SCNG(input_filter) = encoding_filter_script_to_intermediate;
     451           4 :                         LANG_SCNG(output_filter) = encoding_filter_intermediate_to_script;
     452             :                 } else {
     453           3 :                         LANG_SCNG(input_filter) = NULL;
     454           3 :                         LANG_SCNG(output_filter) = NULL;
     455             :                 }
     456           7 :                 return SUCCESS;
     457             :         }
     458             : 
     459          19 :         if (zend_multibyte_check_lexer_compatibility(internal_encoding)) {
     460          19 :                 LANG_SCNG(input_filter) = encoding_filter_script_to_internal;
     461          19 :                 LANG_SCNG(output_filter) = NULL;
     462           0 :         } else if (zend_multibyte_check_lexer_compatibility(LANG_SCNG(script_encoding))) {
     463           0 :                 LANG_SCNG(input_filter) = NULL;
     464           0 :                 LANG_SCNG(output_filter) = encoding_filter_script_to_internal;
     465             :         } else {
     466             :                 /* both script and internal encodings are incompatible w/ flex */
     467           0 :                 LANG_SCNG(input_filter) = encoding_filter_script_to_intermediate;
     468           0 :                 LANG_SCNG(output_filter) = encoding_filter_intermediate_to_internal;
     469             :         }
     470             : 
     471          19 :         return 0;
     472             : }
     473             : 
     474       29676 : ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC)
     475             : {
     476       29676 :         const char *file_path = NULL;
     477             :         char *buf;
     478       29676 :         size_t size, offset = 0;
     479             : 
     480             :         /* The shebang line was read, get the current position to obtain the buffer start */
     481       29676 :         if (CG(start_lineno) == 2 && file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) {
     482           4 :                 if ((offset = ftell(file_handle->handle.fp)) == -1) {
     483           0 :                         offset = 0;
     484             :                 }
     485             :         }
     486             : 
     487       29676 :         if (zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) == FAILURE) {
     488          32 :                 return FAILURE;
     489             :         }
     490             : 
     491       29644 :         zend_llist_add_element(&CG(open_files), file_handle);
     492       29644 :         if (file_handle->handle.stream.handle >= (void*)file_handle && file_handle->handle.stream.handle <= (void*)(file_handle+1)) {
     493       20020 :                 zend_file_handle *fh = (zend_file_handle*)zend_llist_get_last(&CG(open_files));
     494       20020 :                 size_t diff = (char*)file_handle->handle.stream.handle - (char*)file_handle;
     495       20020 :                 fh->handle.stream.handle = (void*)(((char*)fh) + diff);
     496       20020 :                 file_handle->handle.stream.handle = fh->handle.stream.handle;
     497             :         }
     498             : 
     499             :         /* Reset the scanner for scanning the new file */
     500       29644 :         SCNG(yy_in) = file_handle;
     501       29644 :         SCNG(yy_start) = NULL;
     502             : 
     503       29644 :         if (size != -1) {
     504       29644 :                 if (CG(multibyte)) {
     505          28 :                         SCNG(script_org) = (unsigned char*)buf;
     506          28 :                         SCNG(script_org_size) = size;
     507          28 :                         SCNG(script_filtered) = NULL;
     508             : 
     509          28 :                         zend_multibyte_set_filter(NULL TSRMLS_CC);
     510             : 
     511          28 :                         if (SCNG(input_filter)) {
     512          14 :                                 if ((size_t)-1 == SCNG(input_filter)(&SCNG(script_filtered), &SCNG(script_filtered_size), SCNG(script_org), SCNG(script_org_size) TSRMLS_CC)) {
     513           0 :                                         zend_error_noreturn(E_COMPILE_ERROR, "Could not convert the script from the detected "
     514             :                                                         "encoding \"%s\" to a compatible encoding", zend_multibyte_get_encoding_name(LANG_SCNG(script_encoding)));
     515             :                                 }
     516          14 :                                 buf = (char*)SCNG(script_filtered);
     517          14 :                                 size = SCNG(script_filtered_size);
     518             :                         }
     519             :                 }
     520       29644 :                 SCNG(yy_start) = (unsigned char *)buf - offset;
     521       29644 :                 yy_scan_buffer(buf, size TSRMLS_CC);
     522             :         } else {
     523           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "zend_stream_mmap() failed");
     524             :         }
     525             : 
     526       29644 :         BEGIN(INITIAL);
     527             : 
     528       29644 :         if (file_handle->opened_path) {
     529       29614 :                 file_path = file_handle->opened_path;
     530             :         } else {
     531          30 :                 file_path = file_handle->filename;
     532             :         }
     533             : 
     534       29644 :         zend_set_compiled_filename(file_path TSRMLS_CC);
     535             : 
     536       29644 :         if (CG(start_lineno)) {
     537       19737 :                 CG(zend_lineno) = CG(start_lineno);
     538       19737 :                 CG(start_lineno) = 0;
     539             :         } else {
     540        9907 :                 CG(zend_lineno) = 1;
     541             :         }
     542             : 
     543       29644 :         RESET_DOC_COMMENT();
     544       29644 :         CG(increment_lineno) = 0;
     545       29644 :         return SUCCESS;
     546             : }
     547             : END_EXTERN_C()
     548             : 
     549             : 
     550       29645 : ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
     551             : {
     552             :         zend_lex_state original_lex_state;
     553       29645 :         zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
     554       29645 :         zend_op_array *original_active_op_array = CG(active_op_array);
     555       29645 :         zend_op_array *retval=NULL;
     556             :         int compiler_result;
     557       29645 :         zend_bool compilation_successful=0;
     558             :         znode retval_znode;
     559       29645 :         zend_bool original_in_compilation = CG(in_compilation);
     560             : 
     561       29645 :         retval_znode.op_type = IS_CONST;
     562       29645 :         retval_znode.u.constant.type = IS_LONG;
     563       29645 :         retval_znode.u.constant.value.lval = 1;
     564             :         Z_UNSET_ISREF(retval_znode.u.constant);
     565             :         Z_SET_REFCOUNT(retval_znode.u.constant, 1);
     566             : 
     567       29645 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     568             : 
     569       29645 :         retval = op_array; /* success oriented */
     570             : 
     571       29645 :         if (open_file_for_scanning(file_handle TSRMLS_CC)==FAILURE) {
     572          28 :                 if (type==ZEND_REQUIRE) {
     573           1 :                         zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename TSRMLS_CC);
     574           0 :                         zend_bailout();
     575             :                 } else {
     576          27 :                         zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename TSRMLS_CC);
     577             :                 }
     578          27 :                 compilation_successful=0;
     579             :         } else {
     580       29617 :                 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
     581       29617 :                 CG(in_compilation) = 1;
     582       29617 :                 CG(active_op_array) = op_array;
     583       29617 :                 zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
     584       29617 :                 zend_init_compiler_context(TSRMLS_C);
     585       29617 :                 compiler_result = zendparse(TSRMLS_C);
     586       29466 :                 zend_do_return(&retval_znode, 0 TSRMLS_CC);
     587       29466 :                 CG(in_compilation) = original_in_compilation;
     588       29466 :                 if (compiler_result != 0) { /* parser error */
     589          28 :                         zend_bailout();
     590             :                 }
     591       29438 :                 compilation_successful=1;
     592             :         }
     593             : 
     594       29465 :         if (retval) {
     595       29465 :                 CG(active_op_array) = original_active_op_array;
     596       29465 :                 if (compilation_successful) {
     597       29438 :                         pass_two(op_array TSRMLS_CC);
     598       29435 :                         zend_release_labels(0 TSRMLS_CC);
     599             :                 } else {
     600          27 :                         efree(op_array);
     601          27 :                         retval = NULL;
     602             :                 }
     603             :         }
     604       29462 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     605       29462 :         return retval;
     606             : }
     607             : 
     608             : 
     609        3904 : zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC)
     610             : {
     611             :         zend_file_handle file_handle;
     612             :         zval tmp;
     613             :         zend_op_array *retval;
     614        3904 :         char *opened_path = NULL;
     615             : 
     616        3904 :         if (filename->type != IS_STRING) {
     617           0 :                 tmp = *filename;
     618             :                 zval_copy_ctor(&tmp);
     619           0 :                 convert_to_string(&tmp);
     620           0 :                 filename = &tmp;
     621             :         }
     622        3904 :         file_handle.filename = filename->value.str.val;
     623        3904 :         file_handle.free_filename = 0;
     624        3904 :         file_handle.type = ZEND_HANDLE_FILENAME;
     625        3904 :         file_handle.opened_path = NULL;
     626        3904 :         file_handle.handle.fp = NULL;
     627             : 
     628        3904 :         retval = zend_compile_file(&file_handle, type TSRMLS_CC);
     629        3899 :         if (retval && file_handle.handle.stream.handle) {
     630        3872 :                 int dummy = 1;
     631             : 
     632        3872 :                 if (!file_handle.opened_path) {
     633          17 :                         file_handle.opened_path = opened_path = estrndup(filename->value.str.val, filename->value.str.len);
     634             :                 }
     635             : 
     636        3872 :                 zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL);
     637             : 
     638        3872 :                 if (opened_path) {
     639          17 :                         efree(opened_path);
     640             :                 }
     641             :         }
     642        3899 :         zend_destroy_file_handle(&file_handle TSRMLS_CC);
     643             : 
     644        3899 :         if (filename==&tmp) {
     645             :                 zval_dtor(&tmp);
     646             :         }
     647        3899 :         return retval;
     648             : }
     649             : 
     650        1154 : ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_DC)
     651             : {
     652             :         char *buf;
     653             :         size_t size;
     654             : 
     655             :         /* enforce two trailing NULLs for flex... */
     656        1491 :         if (IS_INTERNED(str->value.str.val)) {
     657         337 :                 char *tmp = safe_emalloc(1, str->value.str.len, ZEND_MMAP_AHEAD);
     658         337 :                 memcpy(tmp, str->value.str.val, str->value.str.len + ZEND_MMAP_AHEAD);
     659         337 :                 str->value.str.val = tmp;
     660             :         } else {
     661         817 :                 str->value.str.val = safe_erealloc(str->value.str.val, 1, str->value.str.len, ZEND_MMAP_AHEAD);
     662             :         }
     663             : 
     664        1154 :         memset(str->value.str.val + str->value.str.len, 0, ZEND_MMAP_AHEAD);
     665             : 
     666        1154 :         SCNG(yy_in) = NULL;
     667        1154 :         SCNG(yy_start) = NULL;
     668             : 
     669        1154 :         buf = str->value.str.val;
     670        1154 :         size = str->value.str.len;
     671             : 
     672        1154 :         if (CG(multibyte)) {
     673           0 :                 SCNG(script_org) = (unsigned char*)buf;
     674           0 :                 SCNG(script_org_size) = size;
     675           0 :                 SCNG(script_filtered) = NULL;
     676             : 
     677           0 :                 zend_multibyte_set_filter(zend_multibyte_get_internal_encoding(TSRMLS_C) TSRMLS_CC);
     678             : 
     679           0 :                 if (SCNG(input_filter)) {
     680           0 :                         if ((size_t)-1 == SCNG(input_filter)(&SCNG(script_filtered), &SCNG(script_filtered_size), SCNG(script_org), SCNG(script_org_size) TSRMLS_CC)) {
     681           0 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Could not convert the script from the detected "
     682             :                                                 "encoding \"%s\" to a compatible encoding", zend_multibyte_get_encoding_name(LANG_SCNG(script_encoding)));
     683             :                         }
     684           0 :                         buf = (char*)SCNG(script_filtered);
     685           0 :                         size = SCNG(script_filtered_size);
     686             :                 }
     687             :         }
     688             : 
     689        1154 :         yy_scan_buffer(buf, size TSRMLS_CC);
     690             : 
     691        1154 :         zend_set_compiled_filename(filename TSRMLS_CC);
     692        1154 :         CG(zend_lineno) = 1;
     693        1154 :         CG(increment_lineno) = 0;
     694        1154 :         RESET_DOC_COMMENT();
     695        1154 :         return SUCCESS;
     696             : }
     697             : 
     698             : 
     699         274 : ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D)
     700             : {
     701         274 :         size_t offset = SCNG(yy_cursor) - SCNG(yy_start);
     702         274 :         if (SCNG(input_filter)) {
     703           1 :                 size_t original_offset = offset, length = 0;
     704             :                 do {
     705           7 :                         unsigned char *p = NULL;
     706           7 :                         if ((size_t)-1 == SCNG(input_filter)(&p, &length, SCNG(script_org), offset TSRMLS_CC)) {
     707           0 :                                 return (size_t)-1;
     708             :                         }
     709           7 :                         efree(p);
     710           7 :                         if (length > original_offset) {
     711           0 :                                 offset--;
     712           7 :                         } else if (length < original_offset) {
     713           6 :                                 offset++;
     714             :                         }
     715           7 :                 } while (original_offset != length);
     716             :         }
     717         274 :         return offset;
     718             : }
     719             : 
     720             : 
     721        1065 : zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
     722             : {
     723             :         zend_lex_state original_lex_state;
     724        1065 :         zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
     725        1065 :         zend_op_array *original_active_op_array = CG(active_op_array);
     726             :         zend_op_array *retval;
     727             :         zval tmp;
     728             :         int compiler_result;
     729        1065 :         zend_bool original_in_compilation = CG(in_compilation);
     730             : 
     731        1065 :         if (source_string->value.str.len==0) {
     732           0 :                 efree(op_array);
     733           0 :                 return NULL;
     734             :         }
     735             : 
     736        1065 :         CG(in_compilation) = 1;
     737             : 
     738        1065 :         tmp = *source_string;
     739             :         zval_copy_ctor(&tmp);
     740        1065 :         convert_to_string(&tmp);
     741        1065 :         source_string = &tmp;
     742             : 
     743        1065 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     744        1065 :         if (zend_prepare_string_for_scanning(source_string, filename TSRMLS_CC)==FAILURE) {
     745           0 :                 efree(op_array);
     746           0 :                 retval = NULL;
     747             :         } else {
     748        1065 :                 zend_bool orig_interactive = CG(interactive);
     749             : 
     750        1065 :                 CG(interactive) = 0;
     751        1065 :                 init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
     752        1065 :                 CG(interactive) = orig_interactive;
     753        1065 :                 CG(active_op_array) = op_array;
     754        1065 :                 zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
     755        1065 :                 zend_init_compiler_context(TSRMLS_C);
     756        1065 :                 BEGIN(ST_IN_SCRIPTING);
     757        1065 :                 compiler_result = zendparse(TSRMLS_C);
     758             : 
     759        1063 :                 if (SCNG(script_filtered)) {
     760           0 :                         efree(SCNG(script_filtered));
     761           0 :                         SCNG(script_filtered) = NULL;
     762             :                 }
     763             : 
     764        1063 :                 if (compiler_result != 0) {
     765          10 :                         CG(active_op_array) = original_active_op_array;
     766          10 :                         CG(unclean_shutdown)=1;
     767          10 :                         destroy_op_array(op_array TSRMLS_CC);
     768          10 :                         efree(op_array);
     769          10 :                         retval = NULL;
     770             :                 } else {
     771        1053 :                         zend_do_return(NULL, 0 TSRMLS_CC);
     772        1053 :                         CG(active_op_array) = original_active_op_array;
     773        1053 :                         pass_two(op_array TSRMLS_CC);
     774        1053 :                         zend_release_labels(0 TSRMLS_CC);
     775        1053 :                         retval = op_array;
     776             :                 }
     777             :         }
     778        1063 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     779             :         zval_dtor(&tmp);
     780        1063 :         CG(in_compilation) = original_in_compilation;
     781        1063 :         return retval;
     782             : }
     783             : 
     784             : 
     785             : BEGIN_EXTERN_C()
     786          20 : int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC)
     787             : {
     788             :         zend_lex_state original_lex_state;
     789             :         zend_file_handle file_handle;
     790             : 
     791          20 :         file_handle.type = ZEND_HANDLE_FILENAME;
     792          20 :         file_handle.filename = filename;
     793          20 :         file_handle.free_filename = 0;
     794          20 :         file_handle.opened_path = NULL;
     795          20 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     796          20 :         if (open_file_for_scanning(&file_handle TSRMLS_CC)==FAILURE) {
     797           2 :                 zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename TSRMLS_CC);
     798           2 :                 zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     799           2 :                 return FAILURE;
     800             :         }
     801          18 :         zend_highlight(syntax_highlighter_ini TSRMLS_CC);
     802          18 :         if (SCNG(script_filtered)) {
     803           0 :                 efree(SCNG(script_filtered));
     804           0 :                 SCNG(script_filtered) = NULL;
     805             :         }
     806          18 :         zend_destroy_file_handle(&file_handle TSRMLS_CC);
     807          18 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     808          18 :         return SUCCESS;
     809             : }
     810             : 
     811          14 : int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name TSRMLS_DC)
     812             : {
     813             :         zend_lex_state original_lex_state;
     814          14 :         zval tmp = *str;
     815             : 
     816          14 :         str = &tmp;
     817             :         zval_copy_ctor(str);
     818          14 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     819          14 :         if (zend_prepare_string_for_scanning(str, str_name TSRMLS_CC)==FAILURE) {
     820           0 :                 zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     821           0 :                 return FAILURE;
     822             :         }
     823          14 :         BEGIN(INITIAL);
     824          14 :         zend_highlight(syntax_highlighter_ini TSRMLS_CC);
     825          14 :         if (SCNG(script_filtered)) {
     826           0 :                 efree(SCNG(script_filtered));
     827           0 :                 SCNG(script_filtered) = NULL;
     828             :         }
     829          14 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     830             :         zval_dtor(str);
     831          14 :         return SUCCESS;
     832             : }
     833             : 
     834          11 : ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter, const zend_encoding *old_encoding TSRMLS_DC)
     835             : {
     836             :         size_t length;
     837             :         unsigned char *new_yy_start;
     838             : 
     839             :         /* convert and set */
     840          11 :         if (!SCNG(input_filter)) {
     841           2 :                 if (SCNG(script_filtered)) {
     842           2 :                         efree(SCNG(script_filtered));
     843           2 :                         SCNG(script_filtered) = NULL;
     844             :                 }
     845           2 :                 SCNG(script_filtered_size) = 0;
     846           2 :                 length = SCNG(script_org_size);
     847           2 :                 new_yy_start = SCNG(script_org);
     848             :         } else {
     849           9 :                 if ((size_t)-1 == SCNG(input_filter)(&new_yy_start, &length, SCNG(script_org), SCNG(script_org_size) TSRMLS_CC)) {
     850           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Could not convert the script from the detected "
     851             :                                         "encoding \"%s\" to a compatible encoding", zend_multibyte_get_encoding_name(LANG_SCNG(script_encoding)));
     852             :                 }
     853           9 :                 SCNG(script_filtered) = new_yy_start;
     854           9 :                 SCNG(script_filtered_size) = length;
     855             :         }
     856             : 
     857          11 :         SCNG(yy_cursor) = new_yy_start + (SCNG(yy_cursor) - SCNG(yy_start));
     858          11 :         SCNG(yy_marker) = new_yy_start + (SCNG(yy_marker) - SCNG(yy_start));
     859          11 :         SCNG(yy_text) = new_yy_start + (SCNG(yy_text) - SCNG(yy_start));
     860          11 :         SCNG(yy_limit) = new_yy_start + (SCNG(yy_limit) - SCNG(yy_start));
     861             : 
     862          11 :         SCNG(yy_start) = new_yy_start;
     863          11 : }
     864             : 
     865             : 
     866             : # define zend_copy_value(zendlval, yytext, yyleng) \
     867             :         if (SCNG(output_filter)) { \
     868             :                 size_t sz = 0; \
     869             :                 SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); \
     870             :                 zendlval->value.str.len = sz; \
     871             :         } else { \
     872             :                 zendlval->value.str.val = (char *) estrndup(yytext, yyleng); \
     873             :                 zendlval->value.str.len = yyleng; \
     874             :         }
     875             : 
     876      222781 : static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quote_type TSRMLS_DC)
     877             : {
     878             :         register char *s, *t;
     879             :         char *end;
     880             : 
     881      222781 :         ZVAL_STRINGL(zendlval, str, len, 1);
     882             : 
     883             :         /* convert escape sequences */
     884      222781 :         s = t = zendlval->value.str.val;
     885      222781 :         end = s+zendlval->value.str.len;
     886     4275106 :         while (s<end) {
     887     3829548 :                 if (*s=='\\') {
     888       67807 :                         s++;
     889       67807 :                         if (s >= end) {
     890           4 :                                 *t++ = '\\';
     891           4 :                                 break;
     892             :                         }
     893             : 
     894       67803 :                         switch(*s) {
     895             :                                 case 'n':
     896       55956 :                                         *t++ = '\n';
     897       55956 :                                         zendlval->value.str.len--;
     898       55956 :                                         break;
     899             :                                 case 'r':
     900        4157 :                                         *t++ = '\r';
     901        4157 :                                         zendlval->value.str.len--;
     902        4157 :                                         break;
     903             :                                 case 't':
     904         969 :                                         *t++ = '\t';
     905         969 :                                         zendlval->value.str.len--;
     906         969 :                                         break;
     907             :                                 case 'f':
     908          72 :                                         *t++ = '\f';
     909          72 :                                         zendlval->value.str.len--;
     910          72 :                                         break;
     911             :                                 case 'v':
     912         106 :                                         *t++ = '\v';
     913         106 :                                         zendlval->value.str.len--;
     914         106 :                                         break;
     915             :                                 case 'e':
     916             : #ifdef PHP_WIN32
     917             :                                         *t++ = VK_ESCAPE;
     918             : #else
     919          15 :                                         *t++ = '\e';
     920             : #endif
     921          15 :                                         zendlval->value.str.len--;
     922          15 :                                         break;
     923             :                                 case '"':
     924             :                                 case '`':
     925        1142 :                                         if (*s != quote_type) {
     926          10 :                                                 *t++ = '\\';
     927          10 :                                                 *t++ = *s;
     928          10 :                                                 break;
     929             :                                         }
     930             :                                 case '\\':
     931             :                                 case '$':
     932        2274 :                                         *t++ = *s;
     933        2274 :                                         zendlval->value.str.len--;
     934        2274 :                                         break;
     935             :                                 case 'x':
     936             :                                 case 'X':
     937        5383 :                                         if (ZEND_IS_HEX(*(s+1))) {
     938        2681 :                                                 char hex_buf[3] = { 0, 0, 0 };
     939             : 
     940        2681 :                                                 zendlval->value.str.len--; /* for the 'x' */
     941             : 
     942        2681 :                                                 hex_buf[0] = *(++s);
     943        2681 :                                                 zendlval->value.str.len--;
     944        2681 :                                                 if (ZEND_IS_HEX(*(s+1))) {
     945        2653 :                                                         hex_buf[1] = *(++s);
     946        2653 :                                                         zendlval->value.str.len--;
     947             :                                                 }
     948        2681 :                                                 *t++ = (char) strtol(hex_buf, NULL, 16);
     949             :                                         } else {
     950          21 :                                                 *t++ = '\\';
     951          21 :                                                 *t++ = *s;
     952             :                                         }
     953        2702 :                                         break;
     954             :                                 default:
     955             :                                         /* check for an octal */
     956        2398 :                                         if (ZEND_IS_OCT(*s)) {
     957         856 :                                                 char octal_buf[4] = { 0, 0, 0, 0 };
     958             : 
     959         856 :                                                 octal_buf[0] = *s;
     960         856 :                                                 zendlval->value.str.len--;
     961         856 :                                                 if (ZEND_IS_OCT(*(s+1))) {
     962         205 :                                                         octal_buf[1] = *(++s);
     963         205 :                                                         zendlval->value.str.len--;
     964         205 :                                                         if (ZEND_IS_OCT(*(s+1))) {
     965         181 :                                                                 octal_buf[2] = *(++s);
     966         181 :                                                                 zendlval->value.str.len--;
     967             :                                                         }
     968             :                                                 }
     969         856 :                                                 *t++ = (char) strtol(octal_buf, NULL, 8);
     970             :                                         } else {
     971         686 :                                                 *t++ = '\\';
     972         686 :                                                 *t++ = *s;
     973             :                                         }
     974             :                                         break;
     975             :                         }
     976             :                 } else {
     977     3761741 :                         *t++ = *s;
     978             :                 }
     979             : 
     980     3829544 :                 if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) {
     981       10677 :                         CG(zend_lineno)++;
     982             :                 }
     983     3829544 :                 s++;
     984             :         }
     985      222781 :         *t = 0;
     986      222781 :         if (SCNG(output_filter)) {
     987           8 :                 size_t sz = 0;
     988           8 :                 s = zendlval->value.str.val;
     989           8 :                 SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)s, (size_t)zendlval->value.str.len TSRMLS_CC);
     990           8 :                 zendlval->value.str.len = sz;
     991           8 :                 efree(s);
     992             :         }
     993      222781 : }
     994             : 
     995             : 
     996     8503429 : int lex_scan(zval *zendlval TSRMLS_DC)
     997             : {
     998             : restart:
     999     8503429 :         SCNG(yy_text) = YYCURSOR;
    1000             : 
    1001             : yymore_restart:
    1002             : 
    1003             : /*!re2c
    1004             : re2c:yyfill:check = 0;
    1005             : LNUM    [0-9]+
    1006             : DNUM    ([0-9]*"."[0-9]+)|([0-9]+"."[0-9]*)
    1007             : EXPONENT_DNUM   (({LNUM}|{DNUM})[eE][+-]?{LNUM})
    1008             : HNUM    "0x"[0-9a-fA-F]+
    1009             : BNUM    "0b"[01]+
    1010             : LABEL   [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
    1011             : WHITESPACE [ \n\r\t]+
    1012             : TABS_AND_SPACES [ \t]*
    1013             : TOKENS [;:,.\[\]()|^&+-/*=%!~$<>?@]
    1014             : ANY_CHAR [^]
    1015             : NEWLINE ("\r"|"\n"|"\r\n")
    1016             : 
    1017             : /* compute yyleng before each rule */
    1018             : <!*> := yyleng = YYCURSOR - SCNG(yy_text);
    1019             : 
    1020             : 
    1021             : <ST_IN_SCRIPTING>"exit" {
    1022        1619 :         return T_EXIT;
    1023             : }
    1024             : 
    1025             : <ST_IN_SCRIPTING>"die" {
    1026       13610 :         return T_EXIT;
    1027             : }
    1028             : 
    1029             : <ST_IN_SCRIPTING>"function" {
    1030       37185 :         return T_FUNCTION;
    1031             : }
    1032             : 
    1033             : <ST_IN_SCRIPTING>"const" {
    1034         255 :         return T_CONST;
    1035             : }
    1036             : 
    1037             : <ST_IN_SCRIPTING>"return" {
    1038       51799 :         return T_RETURN;
    1039             : }
    1040             : 
    1041             : <ST_IN_SCRIPTING>"try" {
    1042        2036 :         return T_TRY;
    1043             : }
    1044             : 
    1045             : <ST_IN_SCRIPTING>"catch" {
    1046        2043 :         return T_CATCH;
    1047             : }
    1048             : 
    1049             : <ST_IN_SCRIPTING>"throw" {
    1050         281 :         return T_THROW;
    1051             : }
    1052             : 
    1053             : <ST_IN_SCRIPTING>"if" {
    1054       81358 :         return T_IF;
    1055             : }
    1056             : 
    1057             : <ST_IN_SCRIPTING>"elseif" {
    1058        1847 :         return T_ELSEIF;
    1059             : }
    1060             : 
    1061             : <ST_IN_SCRIPTING>"endif" {
    1062           4 :         return T_ENDIF;
    1063             : }
    1064             : 
    1065             : <ST_IN_SCRIPTING>"else" {
    1066       20187 :         return T_ELSE;
    1067             : }
    1068             : 
    1069             : <ST_IN_SCRIPTING>"while" {
    1070        3180 :         return T_WHILE;
    1071             : }
    1072             : 
    1073             : <ST_IN_SCRIPTING>"endwhile" {
    1074           1 :         return T_ENDWHILE;
    1075             : }
    1076             : 
    1077             : <ST_IN_SCRIPTING>"do" {
    1078         280 :         return T_DO;
    1079             : }
    1080             : 
    1081             : <ST_IN_SCRIPTING>"for" {
    1082        2059 :         return T_FOR;
    1083             : }
    1084             : 
    1085             : <ST_IN_SCRIPTING>"endfor" {
    1086           3 :         return T_ENDFOR;
    1087             : }
    1088             : 
    1089             : <ST_IN_SCRIPTING>"foreach" {
    1090       10950 :         return T_FOREACH;
    1091             : }
    1092             : 
    1093             : <ST_IN_SCRIPTING>"endforeach" {
    1094           0 :         return T_ENDFOREACH;
    1095             : }
    1096             : 
    1097             : <ST_IN_SCRIPTING>"declare" {
    1098          27 :         return T_DECLARE;
    1099             : }
    1100             : 
    1101             : <ST_IN_SCRIPTING>"enddeclare" {
    1102           0 :         return T_ENDDECLARE;
    1103             : }
    1104             : 
    1105             : <ST_IN_SCRIPTING>"instanceof" {
    1106          64 :         return T_INSTANCEOF;
    1107             : }
    1108             : 
    1109             : <ST_IN_SCRIPTING>"as" {
    1110       11038 :         return T_AS;
    1111             : }
    1112             : 
    1113             : <ST_IN_SCRIPTING>"switch" {
    1114         457 :         return T_SWITCH;
    1115             : }
    1116             : 
    1117             : <ST_IN_SCRIPTING>"endswitch" {
    1118           1 :         return T_ENDSWITCH;
    1119             : }
    1120             : 
    1121             : <ST_IN_SCRIPTING>"case" {
    1122        1599 :         return T_CASE;
    1123             : }
    1124             : 
    1125             : <ST_IN_SCRIPTING>"default" {
    1126         275 :         return T_DEFAULT;
    1127             : }
    1128             : 
    1129             : <ST_IN_SCRIPTING>"break" {
    1130        1780 :         return T_BREAK;
    1131             : }
    1132             : 
    1133             : <ST_IN_SCRIPTING>"continue" {
    1134         260 :         return T_CONTINUE;
    1135             : }
    1136             : 
    1137             : <ST_IN_SCRIPTING>"goto" {
    1138          25 :         return T_GOTO;
    1139             : }
    1140             : 
    1141             : <ST_IN_SCRIPTING>"echo" {
    1142       31927 :         return T_ECHO;
    1143             : }
    1144             : 
    1145             : <ST_IN_SCRIPTING>"print" {
    1146        3385 :         return T_PRINT;
    1147             : }
    1148             : 
    1149             : <ST_IN_SCRIPTING>"class" {
    1150        6921 :         return T_CLASS;
    1151             : }
    1152             : 
    1153             : <ST_IN_SCRIPTING>"interface" {
    1154         179 :         return T_INTERFACE;
    1155             : }
    1156             : 
    1157             : <ST_IN_SCRIPTING>"trait" {
    1158         207 :         return T_TRAIT;
    1159             : }
    1160             : 
    1161             : <ST_IN_SCRIPTING>"extends" {
    1162        2329 :         return T_EXTENDS;
    1163             : }
    1164             : 
    1165             : <ST_IN_SCRIPTING>"implements" {
    1166         283 :         return T_IMPLEMENTS;
    1167             : }
    1168             : 
    1169             : <ST_IN_SCRIPTING>"->" {
    1170       44669 :         yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
    1171       44669 :         return T_OBJECT_OPERATOR;
    1172             : }
    1173             : 
    1174             : <ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>{WHITESPACE}+ {
    1175     2451336 :         zendlval->value.str.val = yytext; /* no copying - intentional */
    1176     2451336 :         zendlval->value.str.len = yyleng;
    1177     2451336 :         zendlval->type = IS_STRING;
    1178     2451336 :         HANDLE_NEWLINES(yytext, yyleng);
    1179     2451336 :         return T_WHITESPACE;
    1180             : }
    1181             : 
    1182             : <ST_LOOKING_FOR_PROPERTY>"->" {
    1183         104 :         return T_OBJECT_OPERATOR;
    1184             : }
    1185             : 
    1186             : <ST_LOOKING_FOR_PROPERTY>{LABEL} {
    1187       44555 :         yy_pop_state(TSRMLS_C);
    1188       44555 :         zend_copy_value(zendlval, yytext, yyleng);
    1189       44555 :         zendlval->type = IS_STRING;
    1190       44555 :         return T_STRING;
    1191             : }
    1192             : 
    1193             : <ST_LOOKING_FOR_PROPERTY>{ANY_CHAR} {
    1194         218 :         yyless(0);
    1195         218 :         yy_pop_state(TSRMLS_C);
    1196         218 :         goto restart;
    1197             : }
    1198             : 
    1199             : <ST_IN_SCRIPTING>"::" {
    1200       20854 :         return T_PAAMAYIM_NEKUDOTAYIM;
    1201             : }
    1202             : 
    1203             : <ST_IN_SCRIPTING>"\\" {
    1204         535 :         return T_NS_SEPARATOR;
    1205             : }
    1206             : 
    1207             : <ST_IN_SCRIPTING>"new" {
    1208       13986 :         return T_NEW;
    1209             : }
    1210             : 
    1211             : <ST_IN_SCRIPTING>"clone" {
    1212         102 :         return T_CLONE;
    1213             : }
    1214             : 
    1215             : <ST_IN_SCRIPTING>"var" {
    1216         116 :         return T_VAR;
    1217             : }
    1218             : 
    1219             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("int"|"integer"){TABS_AND_SPACES}")" {
    1220        4912 :         return T_INT_CAST;
    1221             : }
    1222             : 
    1223             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("real"|"double"|"float"){TABS_AND_SPACES}")" {
    1224          66 :         return T_DOUBLE_CAST;
    1225             : }
    1226             : 
    1227             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("string"|"binary"){TABS_AND_SPACES}")" {
    1228        1311 :         return T_STRING_CAST;
    1229             : }
    1230             : 
    1231             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"array"{TABS_AND_SPACES}")" {
    1232          16 :         return T_ARRAY_CAST;
    1233             : }
    1234             : 
    1235             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"object"{TABS_AND_SPACES}")" {
    1236         152 :         return T_OBJECT_CAST;
    1237             : }
    1238             : 
    1239             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("bool"|"boolean"){TABS_AND_SPACES}")" {
    1240          37 :         return T_BOOL_CAST;
    1241             : }
    1242             : 
    1243             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("unset"){TABS_AND_SPACES}")" {
    1244           1 :         return T_UNSET_CAST;
    1245             : }
    1246             : 
    1247             : <ST_IN_SCRIPTING>"eval" {
    1248        2083 :         return T_EVAL;
    1249             : }
    1250             : 
    1251             : <ST_IN_SCRIPTING>"include" {
    1252        2177 :         return T_INCLUDE;
    1253             : }
    1254             : 
    1255             : <ST_IN_SCRIPTING>"include_once" {
    1256         555 :         return T_INCLUDE_ONCE;
    1257             : }
    1258             : 
    1259             : <ST_IN_SCRIPTING>"require" {
    1260        2175 :         return T_REQUIRE;
    1261             : }
    1262             : 
    1263             : <ST_IN_SCRIPTING>"require_once" {
    1264        5828 :         return T_REQUIRE_ONCE;
    1265             : }
    1266             : 
    1267             : <ST_IN_SCRIPTING>"namespace" {
    1268         200 :         return T_NAMESPACE;
    1269             : }
    1270             : 
    1271             : <ST_IN_SCRIPTING>"use" {
    1272         323 :         return T_USE;
    1273             : }
    1274             : 
    1275             : <ST_IN_SCRIPTING>"insteadof" {
    1276          17 :         return T_INSTEADOF;
    1277             : }
    1278             : 
    1279             : <ST_IN_SCRIPTING>"global" {
    1280        4405 :         return T_GLOBAL;
    1281             : }
    1282             : 
    1283             : <ST_IN_SCRIPTING>"isset" {
    1284        5267 :         return T_ISSET;
    1285             : }
    1286             : 
    1287             : <ST_IN_SCRIPTING>"empty" {
    1288        8151 :         return T_EMPTY;
    1289             : }
    1290             : 
    1291             : <ST_IN_SCRIPTING>"__halt_compiler" {
    1292         282 :         return T_HALT_COMPILER;
    1293             : }
    1294             : 
    1295             : <ST_IN_SCRIPTING>"static" {
    1296        9443 :         return T_STATIC;
    1297             : }
    1298             : 
    1299             : <ST_IN_SCRIPTING>"abstract" {
    1300         169 :         return T_ABSTRACT;
    1301             : }
    1302             : 
    1303             : <ST_IN_SCRIPTING>"final" {
    1304          44 :         return T_FINAL;
    1305             : }
    1306             : 
    1307             : <ST_IN_SCRIPTING>"private" {
    1308         716 :         return T_PRIVATE;
    1309             : }
    1310             : 
    1311             : <ST_IN_SCRIPTING>"protected" {
    1312         579 :         return T_PROTECTED;
    1313             : }
    1314             : 
    1315             : <ST_IN_SCRIPTING>"public" {
    1316        4092 :         return T_PUBLIC;
    1317             : }
    1318             : 
    1319             : <ST_IN_SCRIPTING>"unset" {
    1320        1490 :         return T_UNSET;
    1321             : }
    1322             : 
    1323             : <ST_IN_SCRIPTING>"=>" {
    1324       47918 :         return T_DOUBLE_ARROW;
    1325             : }
    1326             : 
    1327             : <ST_IN_SCRIPTING>"list" {
    1328         150 :         return T_LIST;
    1329             : }
    1330             : 
    1331             : <ST_IN_SCRIPTING>"array" {
    1332       31070 :         return T_ARRAY;
    1333             : }
    1334             : 
    1335             : <ST_IN_SCRIPTING>"callable" {
    1336           8 :  return T_CALLABLE;
    1337             : }
    1338             : 
    1339             : <ST_IN_SCRIPTING>"++" {
    1340        6008 :         return T_INC;
    1341             : }
    1342             : 
    1343             : <ST_IN_SCRIPTING>"--" {
    1344         156 :         return T_DEC;
    1345             : }
    1346             : 
    1347             : <ST_IN_SCRIPTING>"===" {
    1348        6075 :         return T_IS_IDENTICAL;
    1349             : }
    1350             : 
    1351             : <ST_IN_SCRIPTING>"!==" {
    1352        8175 :         return T_IS_NOT_IDENTICAL;
    1353             : }
    1354             : 
    1355             : <ST_IN_SCRIPTING>"==" {
    1356       16853 :         return T_IS_EQUAL;
    1357             : }
    1358             : 
    1359             : <ST_IN_SCRIPTING>"!="|"<>" {
    1360        2766 :         return T_IS_NOT_EQUAL;
    1361             : }
    1362             : 
    1363             : <ST_IN_SCRIPTING>"<=" {
    1364        1757 :         return T_IS_SMALLER_OR_EQUAL;
    1365             : }
    1366             : 
    1367             : <ST_IN_SCRIPTING>">=" {
    1368         391 :         return T_IS_GREATER_OR_EQUAL;
    1369             : }
    1370             : 
    1371             : <ST_IN_SCRIPTING>"+=" {
    1372         676 :         return T_PLUS_EQUAL;
    1373             : }
    1374             : 
    1375             : <ST_IN_SCRIPTING>"-=" {
    1376         140 :         return T_MINUS_EQUAL;
    1377             : }
    1378             : 
    1379             : <ST_IN_SCRIPTING>"*=" {
    1380          13 :         return T_MUL_EQUAL;
    1381             : }
    1382             : 
    1383             : <ST_IN_SCRIPTING>"/=" {
    1384           6 :         return T_DIV_EQUAL;
    1385             : }
    1386             : 
    1387             : <ST_IN_SCRIPTING>".=" {
    1388        2886 :         return T_CONCAT_EQUAL;
    1389             : }
    1390             : 
    1391             : <ST_IN_SCRIPTING>"%=" {
    1392           1 :         return T_MOD_EQUAL;
    1393             : }
    1394             : 
    1395             : <ST_IN_SCRIPTING>"<<=" {
    1396           4 :         return T_SL_EQUAL;
    1397             : }
    1398             : 
    1399             : <ST_IN_SCRIPTING>">>=" {
    1400           5 :         return T_SR_EQUAL;
    1401             : }
    1402             : 
    1403             : <ST_IN_SCRIPTING>"&=" {
    1404           3 :         return T_AND_EQUAL;
    1405             : }
    1406             : 
    1407             : <ST_IN_SCRIPTING>"|=" {
    1408          95 :         return T_OR_EQUAL;
    1409             : }
    1410             : 
    1411             : <ST_IN_SCRIPTING>"^=" {
    1412           2 :         return T_XOR_EQUAL;
    1413             : }
    1414             : 
    1415             : <ST_IN_SCRIPTING>"||" {
    1416        9819 :         return T_BOOLEAN_OR;
    1417             : }
    1418             : 
    1419             : <ST_IN_SCRIPTING>"&&" {
    1420        7138 :         return T_BOOLEAN_AND;
    1421             : }
    1422             : 
    1423             : <ST_IN_SCRIPTING>"OR" {
    1424         826 :         return T_LOGICAL_OR;
    1425             : }
    1426             : 
    1427             : <ST_IN_SCRIPTING>"AND" {
    1428          14 :         return T_LOGICAL_AND;
    1429             : }
    1430             : 
    1431             : <ST_IN_SCRIPTING>"XOR" {
    1432           1 :         return T_LOGICAL_XOR;
    1433             : }
    1434             : 
    1435             : <ST_IN_SCRIPTING>"<<" {
    1436         123 :         return T_SL;
    1437             : }
    1438             : 
    1439             : <ST_IN_SCRIPTING>">>" {
    1440          64 :         return T_SR;
    1441             : }
    1442             : 
    1443             : <ST_IN_SCRIPTING>{TOKENS} {
    1444     2875787 :         return yytext[0];
    1445             : }
    1446             : 
    1447             : 
    1448             : <ST_IN_SCRIPTING>"{" {
    1449      135399 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1450      135399 :         return '{';
    1451             : }
    1452             : 
    1453             : 
    1454             : <ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"${" {
    1455          77 :         yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
    1456          77 :         return T_DOLLAR_OPEN_CURLY_BRACES;
    1457             : }
    1458             : 
    1459             : 
    1460             : <ST_IN_SCRIPTING>"}" {
    1461      136230 :         RESET_DOC_COMMENT();
    1462      136230 :         if (!zend_stack_is_empty(&SCNG(state_stack))) {
    1463      136229 :                 yy_pop_state(TSRMLS_C);
    1464             :         }
    1465      136230 :         return '}';
    1466             : }
    1467             : 
    1468             : 
    1469             : <ST_LOOKING_FOR_VARNAME>{LABEL} {
    1470          77 :         zend_copy_value(zendlval, yytext, yyleng);
    1471          77 :         zendlval->type = IS_STRING;
    1472          77 :         yy_pop_state(TSRMLS_C);
    1473          77 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1474          77 :         return T_STRING_VARNAME;
    1475             : }
    1476             : 
    1477             : 
    1478             : <ST_LOOKING_FOR_VARNAME>{ANY_CHAR} {
    1479           0 :         yyless(0);
    1480           0 :         yy_pop_state(TSRMLS_C);
    1481           0 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1482           0 :         goto restart;
    1483             : }
    1484             : 
    1485             : <ST_IN_SCRIPTING>{BNUM} {
    1486          73 :         char *bin = yytext + 2; /* Skip "0b" */
    1487          73 :         int len = yyleng - 2;
    1488             : 
    1489             :         /* Skip any leading 0s */
    1490         148 :         while (*bin == '0') {
    1491           2 :                 ++bin;
    1492           2 :                 --len;
    1493             :         }
    1494             : 
    1495          73 :         if (len < SIZEOF_LONG * 8) {
    1496          68 :                 if (len == 0) {
    1497           1 :                         zendlval->value.lval = 0;
    1498             :                 } else {
    1499          67 :                         zendlval->value.lval = strtol(bin, NULL, 2);
    1500             :                 }
    1501          68 :                 zendlval->type = IS_LONG;
    1502          68 :                 return T_LNUMBER;
    1503             :         } else {
    1504           5 :                 zendlval->value.dval = zend_bin_strtod(bin, NULL);
    1505           5 :                 zendlval->type = IS_DOUBLE;
    1506           5 :                 return T_DNUMBER;
    1507             :         }
    1508             : }
    1509             : 
    1510             : <ST_IN_SCRIPTING>{LNUM} {
    1511      163510 :         if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
    1512      163331 :                 zendlval->value.lval = strtol(yytext, NULL, 0);
    1513             :         } else {
    1514         179 :                 errno = 0;
    1515         179 :                 zendlval->value.lval = strtol(yytext, NULL, 0);
    1516         179 :                 if (errno == ERANGE) { /* Overflow */
    1517          45 :                         if (yytext[0] == '0') { /* octal overflow */
    1518           1 :                                 zendlval->value.dval = zend_oct_strtod(yytext, NULL);
    1519             :                         } else {
    1520          44 :                                 zendlval->value.dval = zend_strtod(yytext, NULL);
    1521             :                         }
    1522          45 :                         zendlval->type = IS_DOUBLE;
    1523          45 :                         return T_DNUMBER;
    1524             :                 }
    1525             :         }
    1526             : 
    1527      163465 :         zendlval->type = IS_LONG;
    1528      163465 :         return T_LNUMBER;
    1529             : }
    1530             : 
    1531             : <ST_IN_SCRIPTING>{HNUM} {
    1532        3137 :         char *hex = yytext + 2; /* Skip "0x" */
    1533        3137 :         int len = yyleng - 2;
    1534             : 
    1535             :         /* Skip any leading 0s */
    1536        7833 :         while (*hex == '0') {
    1537        1559 :                 hex++;
    1538        1559 :                 len--;
    1539             :         }
    1540             : 
    1541        3137 :         if (len < SIZEOF_LONG * 2 || (len == SIZEOF_LONG * 2 && *hex <= '7')) {
    1542        3137 :                 if (len == 0) {
    1543          58 :                         zendlval->value.lval = 0;
    1544             :                 } else {
    1545        3079 :                         zendlval->value.lval = strtol(hex, NULL, 16);
    1546             :                 }
    1547        3137 :                 zendlval->type = IS_LONG;
    1548        3137 :                 return T_LNUMBER;
    1549             :         } else {
    1550           0 :                 zendlval->value.dval = zend_hex_strtod(hex, NULL);
    1551           0 :                 zendlval->type = IS_DOUBLE;
    1552           0 :                 return T_DNUMBER;
    1553             :         }
    1554             : }
    1555             : 
    1556             : <ST_VAR_OFFSET>[0]|([1-9][0-9]*) { /* Offset could be treated as a long */
    1557         768 :         if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) {
    1558         384 :                 zendlval->value.lval = strtol(yytext, NULL, 10);
    1559         384 :                 zendlval->type = IS_LONG;
    1560             :         } else {
    1561           0 :                 zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
    1562           0 :                 zendlval->value.str.len = yyleng;
    1563           0 :                 zendlval->type = IS_STRING;
    1564             :         }
    1565         384 :         return T_NUM_STRING;
    1566             : }
    1567             : 
    1568             : <ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM} { /* Offset must be treated as a string */
    1569           0 :         zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
    1570           0 :         zendlval->value.str.len = yyleng;
    1571           0 :         zendlval->type = IS_STRING;
    1572           0 :         return T_NUM_STRING;
    1573             : }
    1574             : 
    1575             : <ST_IN_SCRIPTING>{DNUM}|{EXPONENT_DNUM} {
    1576        6826 :         zendlval->value.dval = zend_strtod(yytext, NULL);
    1577        6826 :         zendlval->type = IS_DOUBLE;
    1578        6826 :         return T_DNUMBER;
    1579             : }
    1580             : 
    1581             : <ST_IN_SCRIPTING>"__CLASS__" {
    1582          82 :         const char *class_name = NULL;
    1583             :         
    1584         168 :         if (CG(active_class_entry)
    1585             :                 && (ZEND_ACC_TRAIT ==
    1586          81 :                         (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT))) {
    1587             :                 /* We create a special __CLASS__ constant that is going to be resolved
    1588             :                    at run-time */
    1589           5 :                 zendlval->value.str.len = sizeof("__CLASS__")-1;
    1590           5 :                 zendlval->value.str.val = estrndup("__CLASS__", zendlval->value.str.len);
    1591           5 :                 zendlval->type = IS_CONSTANT;
    1592             :         } else {
    1593          77 :                 if (CG(active_class_entry)) {
    1594          76 :                         class_name = CG(active_class_entry)->name;
    1595             :                 }
    1596             :                 
    1597          77 :                 if (!class_name) {
    1598           1 :                         class_name = "";
    1599             :                 }
    1600             :                 
    1601          77 :                 zendlval->value.str.len = strlen(class_name);
    1602          77 :                 zendlval->value.str.val = estrndup(class_name, zendlval->value.str.len);
    1603          77 :                 zendlval->type = IS_STRING;
    1604             :         }
    1605          82 :         return T_CLASS_C;
    1606             : }
    1607             : 
    1608             : <ST_IN_SCRIPTING>"__TRAIT__" {
    1609           5 :         const char *trait_name = NULL;
    1610             :         
    1611           7 :         if (CG(active_class_entry)
    1612             :                 && (ZEND_ACC_TRAIT == 
    1613           2 :                         (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT))) {
    1614           1 :                 trait_name = CG(active_class_entry)->name;
    1615             :         }
    1616             :         
    1617           5 :         if (!trait_name) {
    1618           4 :                 trait_name = "";
    1619             :         }
    1620             :         
    1621           5 :         zendlval->value.str.len = strlen(trait_name);
    1622           5 :         zendlval->value.str.val = estrndup(trait_name, zendlval->value.str.len);
    1623           5 :         zendlval->type = IS_STRING;
    1624             :         
    1625           5 :         return T_TRAIT_C;
    1626             : }
    1627             : 
    1628             : <ST_IN_SCRIPTING>"__FUNCTION__" {
    1629         104 :         const char *func_name = NULL;
    1630             : 
    1631         104 :         if (CG(active_op_array)) {
    1632         103 :                 func_name = CG(active_op_array)->function_name;
    1633             :         }
    1634             : 
    1635         104 :         if (!func_name) {
    1636           2 :                 func_name = "";
    1637             :         }
    1638         104 :         zendlval->value.str.len = strlen(func_name);
    1639         104 :         zendlval->value.str.val = estrndup(func_name, zendlval->value.str.len);
    1640         104 :         zendlval->type = IS_STRING;
    1641         104 :         return T_FUNC_C;
    1642             : }
    1643             : 
    1644             : <ST_IN_SCRIPTING>"__METHOD__" {
    1645         783 :         const char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL;
    1646         783 :         const char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL;
    1647         783 :         size_t len = 0;
    1648             : 
    1649         783 :         if (class_name) {
    1650         760 :                 len += strlen(class_name) + 2;
    1651             :         }
    1652         783 :         if (func_name) {
    1653         781 :                 len += strlen(func_name);
    1654             :         }
    1655             : 
    1656         783 :         zendlval->value.str.len = zend_spprintf(&zendlval->value.str.val, 0, "%s%s%s",
    1657             :                 class_name ? class_name : "",
    1658             :                 class_name && func_name ? "::" : "",
    1659             :                 func_name ? func_name : ""
    1660             :                 );
    1661         783 :         zendlval->type = IS_STRING;
    1662         783 :         return T_METHOD_C;
    1663             : }
    1664             : 
    1665             : <ST_IN_SCRIPTING>"__LINE__" {
    1666          15 :         zendlval->value.lval = CG(zend_lineno);
    1667          15 :         zendlval->type = IS_LONG;
    1668          15 :         return T_LINE;
    1669             : }
    1670             : 
    1671             : <ST_IN_SCRIPTING>"__FILE__" {
    1672        9073 :         char *filename = zend_get_compiled_filename(TSRMLS_C);
    1673             : 
    1674        9073 :         if (!filename) {
    1675           0 :                 filename = "";
    1676             :         }
    1677        9073 :         zendlval->value.str.len = strlen(filename);
    1678        9073 :         zendlval->value.str.val = estrndup(filename, zendlval->value.str.len);
    1679        9073 :         zendlval->type = IS_STRING;
    1680        9073 :         return T_FILE;
    1681             : }
    1682             : 
    1683             : <ST_IN_SCRIPTING>"__DIR__" {
    1684         323 :         char *filename = zend_get_compiled_filename(TSRMLS_C);
    1685         323 :         const size_t filename_len = strlen(filename);
    1686             :         char *dirname;
    1687             : 
    1688         323 :         if (!filename) {
    1689           0 :                 filename = "";
    1690             :         }
    1691             : 
    1692         323 :         dirname = estrndup(filename, filename_len);
    1693         323 :         zend_dirname(dirname, filename_len);
    1694             : 
    1695         323 :         if (strcmp(dirname, ".") == 0) {
    1696           0 :                 dirname = erealloc(dirname, MAXPATHLEN);
    1697             : #if HAVE_GETCWD
    1698           0 :                 VCWD_GETCWD(dirname, MAXPATHLEN);
    1699             : #elif HAVE_GETWD
    1700             :                 VCWD_GETWD(dirname);
    1701             : #endif
    1702             :         }
    1703             : 
    1704         323 :         zendlval->value.str.len = strlen(dirname);
    1705         323 :         zendlval->value.str.val = dirname;
    1706         323 :         zendlval->type = IS_STRING;
    1707         323 :         return T_DIR;
    1708             : }
    1709             : 
    1710             : <ST_IN_SCRIPTING>"__NAMESPACE__" {
    1711          33 :         if (CG(current_namespace)) {
    1712          25 :                 *zendlval = *CG(current_namespace);
    1713             :                 zval_copy_ctor(zendlval);
    1714             :         } else {
    1715           8 :                 ZVAL_EMPTY_STRING(zendlval);
    1716             :         }
    1717          33 :         return T_NS_C;
    1718             : }
    1719             : 
    1720             : <INITIAL>"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPACE}*("php"|"\"php\""|"'php'"){WHITESPACE}*">" {
    1721           5 :         YYCTYPE *bracket = (YYCTYPE*)zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1));
    1722             : 
    1723           5 :         if (bracket != SCNG(yy_text)) {
    1724             :                 /* Handle previously scanned HTML, as possible <script> tags found are assumed to not be PHP's */
    1725           1 :                 YYCURSOR = bracket;
    1726           1 :                 goto inline_html;
    1727             :         }
    1728             : 
    1729           4 :         HANDLE_NEWLINES(yytext, yyleng);
    1730           4 :         zendlval->value.str.val = yytext; /* no copying - intentional */
    1731           4 :         zendlval->value.str.len = yyleng;
    1732           4 :         zendlval->type = IS_STRING;
    1733           4 :         BEGIN(ST_IN_SCRIPTING);
    1734           4 :         return T_OPEN_TAG;
    1735             : }
    1736             : 
    1737             : 
    1738             : <INITIAL>"<%=" {
    1739           3 :         if (CG(asp_tags)) {
    1740           2 :                 zendlval->value.str.val = yytext; /* no copying - intentional */
    1741           2 :                 zendlval->value.str.len = yyleng;
    1742           2 :                 zendlval->type = IS_STRING;
    1743           2 :                 BEGIN(ST_IN_SCRIPTING);
    1744           2 :                 return T_OPEN_TAG_WITH_ECHO;
    1745             :         } else {
    1746           1 :                 goto inline_char_handler;
    1747             :         }
    1748             : }
    1749             : 
    1750             : 
    1751             : <INITIAL>"<?=" {
    1752           6 :         zendlval->value.str.val = yytext; /* no copying - intentional */
    1753           6 :         zendlval->value.str.len = yyleng;
    1754           6 :         zendlval->type = IS_STRING;
    1755           6 :         BEGIN(ST_IN_SCRIPTING);
    1756           6 :         return T_OPEN_TAG_WITH_ECHO;
    1757             : }
    1758             : 
    1759             : 
    1760             : <INITIAL>"<%" {
    1761           0 :         if (CG(asp_tags)) {
    1762           0 :                 zendlval->value.str.val = yytext; /* no copying - intentional */
    1763           0 :                 zendlval->value.str.len = yyleng;
    1764           0 :                 zendlval->type = IS_STRING;
    1765           0 :                 BEGIN(ST_IN_SCRIPTING);
    1766           0 :                 return T_OPEN_TAG;
    1767             :         } else {
    1768           0 :                 goto inline_char_handler;
    1769             :         }
    1770             : }
    1771             : 
    1772             : 
    1773             : <INITIAL>"<?php"([ \t]|{NEWLINE}) {
    1774       30135 :         zendlval->value.str.val = yytext; /* no copying - intentional */
    1775       30135 :         zendlval->value.str.len = yyleng;
    1776       30135 :         zendlval->type = IS_STRING;
    1777       30135 :         HANDLE_NEWLINE(yytext[yyleng-1]);
    1778       30135 :         BEGIN(ST_IN_SCRIPTING);
    1779       30135 :         return T_OPEN_TAG;
    1780             : }
    1781             : 
    1782             : 
    1783             : <INITIAL>"<?" {
    1784           5 :         if (CG(short_tags)) {
    1785           4 :                 zendlval->value.str.val = yytext; /* no copying - intentional */
    1786           4 :                 zendlval->value.str.len = yyleng;
    1787           4 :                 zendlval->type = IS_STRING;
    1788           4 :                 BEGIN(ST_IN_SCRIPTING);
    1789           4 :                 return T_OPEN_TAG;
    1790             :         } else {
    1791           1 :                 goto inline_char_handler;
    1792             :         }
    1793             : }
    1794             : 
    1795             : <INITIAL>{ANY_CHAR} {
    1796       31685 :         if (YYCURSOR > YYLIMIT) {
    1797       28019 :                 return 0;
    1798             :         }
    1799             : 
    1800             : inline_char_handler:
    1801             : 
    1802             :         while (1) {
    1803        3782 :                 YYCTYPE *ptr = memchr(YYCURSOR, '<', YYLIMIT - YYCURSOR);
    1804             : 
    1805        3782 :                 YYCURSOR = ptr ? ptr + 1 : YYLIMIT;
    1806             : 
    1807        3782 :                 if (YYCURSOR < YYLIMIT) {
    1808         342 :                         switch (*YYCURSOR) {
    1809             :                                 case '?':
    1810         221 :                                         if (CG(short_tags) || !strncasecmp((char*)YYCURSOR + 1, "php", 3) || (*(YYCURSOR + 1) == '=')) { /* Assume [ \t\n\r] follows "php" */
    1811             :                                                 break;
    1812             :                                         }
    1813           1 :                                         continue;
    1814             :                                 case '%':
    1815           3 :                                         if (CG(asp_tags)) {
    1816           2 :                                                 break;
    1817             :                                         }
    1818           1 :                                         continue;
    1819             :                                 case 's':
    1820             :                                 case 'S':
    1821             :                                         /* Probably NOT an opening PHP <script> tag, so don't end the HTML chunk yet
    1822             :                                          * If it is, the PHP <script> tag rule checks for any HTML scanned before it */
    1823           6 :                                         YYCURSOR--;
    1824           6 :                                         yymore();
    1825             :                                 default:
    1826         112 :                                         continue;
    1827             :                         }
    1828             : 
    1829         222 :                         YYCURSOR--;
    1830             :                 }
    1831             : 
    1832        3662 :                 break;
    1833         114 :         }
    1834             : 
    1835             : inline_html:
    1836        3663 :         yyleng = YYCURSOR - SCNG(yy_text);
    1837             : 
    1838        3663 :         if (SCNG(output_filter)) {
    1839             :                 int readsize;
    1840           1 :                 size_t sz = 0;
    1841           1 :                 readsize = SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC);
    1842           1 :                 zendlval->value.str.len = sz;
    1843           1 :                 if (readsize < yyleng) {
    1844           0 :                         yyless(readsize);
    1845             :                 }
    1846             :         } else {
    1847        3662 :           zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
    1848        3662 :           zendlval->value.str.len = yyleng;
    1849             :         }
    1850        3663 :         zendlval->type = IS_STRING;
    1851        3663 :         HANDLE_NEWLINES(yytext, yyleng);
    1852        3663 :         return T_INLINE_HTML;
    1853             : }
    1854             : 
    1855             : 
    1856             : /* Make sure a label character follows "->", otherwise there is no property
    1857             :  * and "->" will be taken literally
    1858             :  */
    1859             : <ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"->"[a-zA-Z_\x7f-\xff] {
    1860         104 :         yyless(yyleng - 3);
    1861         104 :         yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
    1862         104 :         zend_copy_value(zendlval, (yytext+1), (yyleng-1));
    1863         104 :         zendlval->type = IS_STRING;
    1864         104 :         return T_VARIABLE;
    1865             : }
    1866             : 
    1867             : /* A [ always designates a variable offset, regardless of what follows
    1868             :  */
    1869             : <ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"[" {
    1870         978 :         yyless(yyleng - 1);
    1871         978 :         yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
    1872         978 :         zend_copy_value(zendlval, (yytext+1), (yyleng-1));
    1873         978 :         zendlval->type = IS_STRING;
    1874         978 :         return T_VARIABLE;
    1875             : }
    1876             : 
    1877             : <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} {
    1878      884542 :         zend_copy_value(zendlval, (yytext+1), (yyleng-1));
    1879      884542 :         zendlval->type = IS_STRING;
    1880      884542 :         return T_VARIABLE;
    1881             : }
    1882             : 
    1883             : <ST_VAR_OFFSET>"]" {
    1884         976 :         yy_pop_state(TSRMLS_C);
    1885         976 :         return ']';
    1886             : }
    1887             : 
    1888             : <ST_VAR_OFFSET>{TOKENS}|[{}"`] {
    1889             :         /* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
    1890         978 :         return yytext[0];
    1891             : }
    1892             : 
    1893             : <ST_VAR_OFFSET>[ \n\r\t\\'#] {
    1894             :         /* Invalid rule to return a more explicit parse error with proper line number */
    1895           2 :         yyless(0);
    1896           2 :         yy_pop_state(TSRMLS_C);
    1897           2 :         return T_ENCAPSED_AND_WHITESPACE;
    1898             : }
    1899             : 
    1900             : <ST_IN_SCRIPTING,ST_VAR_OFFSET>{LABEL} {
    1901      511736 :         zend_copy_value(zendlval, yytext, yyleng);
    1902      511736 :         zendlval->type = IS_STRING;
    1903      511736 :         return T_STRING;
    1904             : }
    1905             : 
    1906             : 
    1907             : <ST_IN_SCRIPTING>"#"|"//" {
    1908     1649092 :         while (YYCURSOR < YYLIMIT) {
    1909     1598089 :                 switch (*YYCURSOR++) {
    1910             :                         case '\r':
    1911         122 :                                 if (*YYCURSOR == '\n') {
    1912         122 :                                         YYCURSOR++;
    1913             :                                 }
    1914             :                                 /* fall through */
    1915             :                         case '\n':
    1916       50991 :                                 CG(zend_lineno)++;
    1917       50991 :                                 break;
    1918             :                         case '%':
    1919          28 :                                 if (!CG(asp_tags)) {
    1920          28 :                                         continue;
    1921             :                                 }
    1922             :                                 /* fall through */
    1923             :                         case '?':
    1924         564 :                                 if (*YYCURSOR == '>') {
    1925           2 :                                         YYCURSOR--;
    1926           2 :                                         break;
    1927             :                                 }
    1928             :                                 /* fall through */
    1929             :                         default:
    1930     1547068 :                                 continue;
    1931             :                 }
    1932             : 
    1933       50993 :                 break;
    1934             :         }
    1935             : 
    1936       50998 :         yyleng = YYCURSOR - SCNG(yy_text);
    1937             : 
    1938       50998 :         return T_COMMENT;
    1939             : }
    1940             : 
    1941             : <ST_IN_SCRIPTING>"/*"|"/**"{WHITESPACE} {
    1942             :         int doc_com;
    1943             : 
    1944       27339 :         if (yyleng > 2) {
    1945        2518 :                 doc_com = 1;
    1946        2518 :                 RESET_DOC_COMMENT();
    1947             :         } else {
    1948       24821 :                 doc_com = 0;
    1949             :         }
    1950             : 
    1951     4072247 :         while (YYCURSOR < YYLIMIT) {
    1952     4044907 :                 if (*YYCURSOR++ == '*' && *YYCURSOR == '/') {
    1953       27338 :                         break;
    1954             :                 }
    1955             :         }
    1956             : 
    1957       27339 :         if (YYCURSOR < YYLIMIT) {
    1958       27338 :                 YYCURSOR++;
    1959             :         } else {
    1960           1 :                 zend_error(E_COMPILE_WARNING, "Unterminated comment starting line %d", CG(zend_lineno));
    1961             :         }
    1962             : 
    1963       27339 :         yyleng = YYCURSOR - SCNG(yy_text);
    1964       27339 :         HANDLE_NEWLINES(yytext, yyleng);
    1965             : 
    1966       27339 :         if (doc_com) {
    1967        2518 :                 CG(doc_comment) = estrndup(yytext, yyleng);
    1968        2518 :                 CG(doc_comment_len) = yyleng;
    1969        2518 :                 return T_DOC_COMMENT;
    1970             :         }
    1971             : 
    1972       24821 :         return T_COMMENT;
    1973             : }
    1974             : 
    1975             : <ST_IN_SCRIPTING>("?>"|"</script"{WHITESPACE}*">"){NEWLINE}? {
    1976       28435 :         zendlval->value.str.val = yytext; /* no copying - intentional */
    1977       28435 :         zendlval->value.str.len = yyleng;
    1978       28435 :         zendlval->type = IS_STRING;
    1979       28435 :         BEGIN(INITIAL);
    1980       28435 :         return T_CLOSE_TAG;  /* implicit ';' at php-end tag */
    1981             : }
    1982             : 
    1983             : 
    1984             : <ST_IN_SCRIPTING>"%>"{NEWLINE}? {
    1985           2 :         if (CG(asp_tags)) {
    1986           2 :                 BEGIN(INITIAL);
    1987           2 :                 zendlval->value.str.len = yyleng;
    1988           2 :                 zendlval->type = IS_STRING;
    1989           2 :                 zendlval->value.str.val = yytext; /* no copying - intentional */
    1990           2 :                 return T_CLOSE_TAG;  /* implicit ';' at php-end tag */
    1991             :         } else {
    1992           0 :                 yyless(1);
    1993           0 :                 return yytext[0];
    1994             :         }
    1995             : }
    1996             : 
    1997             : 
    1998             : <ST_IN_SCRIPTING>b?['] {
    1999             :         register char *s, *t;
    2000             :         char *end;
    2001      282046 :         int bprefix = (yytext[0] != '\'') ? 1 : 0;
    2002             : 
    2003             :         while (1) {
    2004     2841050 :                 if (YYCURSOR < YYLIMIT) {
    2005     2841050 :                         if (*YYCURSOR == '\'') {
    2006      282046 :                                 YYCURSOR++;
    2007      282046 :                                 yyleng = YYCURSOR - SCNG(yy_text);
    2008             : 
    2009      282046 :                                 break;
    2010     2559004 :                         } else if (*YYCURSOR++ == '\\' && YYCURSOR < YYLIMIT) {
    2011       12860 :                                 YYCURSOR++;
    2012             :                         }
    2013             :                 } else {
    2014           0 :                         yyleng = YYLIMIT - SCNG(yy_text);
    2015             : 
    2016             :                         /* Unclosed single quotes; treat similar to double quotes, but without a separate token
    2017             :                          * for ' (unrecognized by parser), instead of old flex fallback to "Unexpected character..."
    2018             :                          * rule, which continued in ST_IN_SCRIPTING state after the quote */
    2019           0 :                         return T_ENCAPSED_AND_WHITESPACE;
    2020             :                 }
    2021     2559004 :         }
    2022             : 
    2023      282046 :         zendlval->value.str.val = estrndup(yytext+bprefix+1, yyleng-bprefix-2);
    2024      282046 :         zendlval->value.str.len = yyleng-bprefix-2;
    2025      282046 :         zendlval->type = IS_STRING;
    2026             : 
    2027             :         /* convert escape sequences */
    2028      282046 :         s = t = zendlval->value.str.val;
    2029      282046 :         end = s+zendlval->value.str.len;
    2030     3123096 :         while (s<end) {
    2031     2559004 :                 if (*s=='\\') {
    2032       12860 :                         s++;
    2033             : 
    2034       12860 :                         switch(*s) {
    2035             :                                 case '\\':
    2036             :                                 case '\'':
    2037        1576 :                                         *t++ = *s;
    2038        1576 :                                         zendlval->value.str.len--;
    2039        1576 :                                         break;
    2040             :                                 default:
    2041       11284 :                                         *t++ = '\\';
    2042       11284 :                                         *t++ = *s;
    2043             :                                         break;
    2044             :                         }
    2045             :                 } else {
    2046     2546144 :                         *t++ = *s;
    2047             :                 }
    2048             : 
    2049     2559004 :                 if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) {
    2050        1262 :                         CG(zend_lineno)++;
    2051             :                 }
    2052     2559004 :                 s++;
    2053             :         }
    2054      282046 :         *t = 0;
    2055             : 
    2056      282046 :         if (SCNG(output_filter)) {
    2057           0 :                 size_t sz = 0;
    2058           0 :                 s = zendlval->value.str.val;
    2059           0 :                 SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)s, (size_t)zendlval->value.str.len TSRMLS_CC);
    2060           0 :                 zendlval->value.str.len = sz;
    2061           0 :                 efree(s);
    2062             :         }
    2063      282046 :         return T_CONSTANT_ENCAPSED_STRING;
    2064             : }
    2065             : 
    2066             : 
    2067             : <ST_IN_SCRIPTING>b?["] {
    2068      209135 :         int bprefix = (yytext[0] != '"') ? 1 : 0;
    2069             : 
    2070     3844559 :         while (YYCURSOR < YYLIMIT) {
    2071     3635421 :                 switch (*YYCURSOR++) {
    2072             :                         case '"':
    2073      194721 :                                 yyleng = YYCURSOR - SCNG(yy_text);
    2074      194721 :                                 zend_scan_escape_string(zendlval, yytext+bprefix+1, yyleng-bprefix-2, '"' TSRMLS_CC);
    2075      194721 :                                 return T_CONSTANT_ENCAPSED_STRING;
    2076             :                         case '$':
    2077       14268 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2078             :                                         break;
    2079             :                                 }
    2080         399 :                                 continue;
    2081             :                         case '{':
    2082         717 :                                 if (*YYCURSOR == '$') {
    2083         542 :                                         break;
    2084             :                                 }
    2085         175 :                                 continue;
    2086             :                         case '\\':
    2087       59343 :                                 if (YYCURSOR < YYLIMIT) {
    2088       59343 :                                         YYCURSOR++;
    2089             :                                 }
    2090             :                                 /* fall through */
    2091             :                         default:
    2092     3425715 :                                 continue;
    2093             :                 }
    2094             : 
    2095       14411 :                 YYCURSOR--;
    2096       14411 :                 break;
    2097             :         }
    2098             : 
    2099             :         /* Remember how much was scanned to save rescanning */
    2100       14414 :         SET_DOUBLE_QUOTES_SCANNED_LENGTH(YYCURSOR - SCNG(yy_text) - yyleng);
    2101             : 
    2102       14414 :         YYCURSOR = SCNG(yy_text) + yyleng;
    2103             : 
    2104       14414 :         BEGIN(ST_DOUBLE_QUOTES);
    2105       14414 :         return '"';
    2106             : }
    2107             : 
    2108             : 
    2109             : <ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|([']{LABEL}['])|(["]{LABEL}["])){NEWLINE} {
    2110             :         char *s;
    2111        1480 :         int bprefix = (yytext[0] != '<') ? 1 : 0;
    2112             : 
    2113             :         /* save old heredoc label */
    2114        1480 :         Z_STRVAL_P(zendlval) = CG(heredoc);
    2115        1480 :         Z_STRLEN_P(zendlval) = CG(heredoc_len);
    2116             : 
    2117        1480 :         CG(zend_lineno)++;
    2118        1480 :         CG(heredoc_len) = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
    2119        1480 :         s = yytext+bprefix+3;
    2120        2995 :         while ((*s == ' ') || (*s == '\t')) {
    2121          35 :                 s++;
    2122          35 :                 CG(heredoc_len)--;
    2123             :         }
    2124             : 
    2125        1480 :         if (*s == '\'') {
    2126          51 :                 s++;
    2127          51 :                 CG(heredoc_len) -= 2;
    2128             : 
    2129          51 :                 BEGIN(ST_NOWDOC);
    2130             :         } else {
    2131        1429 :                 if (*s == '"') {
    2132           7 :                         s++;
    2133           7 :                         CG(heredoc_len) -= 2;
    2134             :                 }
    2135             : 
    2136        1429 :                 BEGIN(ST_HEREDOC);
    2137             :         }
    2138             : 
    2139        1480 :         CG(heredoc) = estrndup(s, CG(heredoc_len));
    2140             : 
    2141             :         /* Check for ending label on the next line */
    2142        1480 :         if (CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, CG(heredoc_len))) {
    2143          64 :                 YYCTYPE *end = YYCURSOR + CG(heredoc_len);
    2144             : 
    2145          64 :                 if (*end == ';') {
    2146          59 :                         end++;
    2147             :                 }
    2148             : 
    2149          64 :                 if (*end == '\n' || *end == '\r') {
    2150          60 :                         BEGIN(ST_END_HEREDOC);
    2151             :                 }
    2152             :         }
    2153             : 
    2154        1480 :         return T_START_HEREDOC;
    2155             : }
    2156             : 
    2157             : 
    2158             : <ST_IN_SCRIPTING>[`] {
    2159         109 :         BEGIN(ST_BACKQUOTE);
    2160         109 :         return '`';
    2161             : }
    2162             : 
    2163             : 
    2164             : <ST_END_HEREDOC>{ANY_CHAR} {
    2165        1477 :         YYCURSOR += CG(heredoc_len) - 1;
    2166        1477 :         yyleng = CG(heredoc_len);
    2167             : 
    2168        1477 :         Z_STRVAL_P(zendlval) = CG(heredoc);
    2169        1477 :         Z_STRLEN_P(zendlval) = CG(heredoc_len);
    2170        1477 :         CG(heredoc) = NULL;
    2171        1477 :         CG(heredoc_len) = 0;
    2172        1477 :         BEGIN(ST_IN_SCRIPTING);
    2173        1477 :         return T_END_HEREDOC;
    2174             : }
    2175             : 
    2176             : 
    2177             : <ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"{$" {
    2178         840 :         zendlval->value.lval = (long) '{';
    2179         840 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    2180         840 :         yyless(1);
    2181         840 :         return T_CURLY_OPEN;
    2182             : }
    2183             : 
    2184             : 
    2185             : <ST_DOUBLE_QUOTES>["] {
    2186       14409 :         BEGIN(ST_IN_SCRIPTING);
    2187       14409 :         return '"';
    2188             : }
    2189             : 
    2190             : <ST_BACKQUOTE>[`] {
    2191         109 :         BEGIN(ST_IN_SCRIPTING);
    2192         109 :         return '`';
    2193             : }
    2194             : 
    2195             : 
    2196             : <ST_DOUBLE_QUOTES>{ANY_CHAR} {
    2197       26018 :         if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) {
    2198        9952 :                 YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1;
    2199        9952 :                 SET_DOUBLE_QUOTES_SCANNED_LENGTH(0);
    2200             : 
    2201        9952 :                 goto double_quotes_scan_done;
    2202             :         }
    2203             : 
    2204       16066 :         if (YYCURSOR > YYLIMIT) {
    2205           3 :                 return 0;
    2206             :         }
    2207       16063 :         if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
    2208        2226 :                 YYCURSOR++;
    2209             :         }
    2210             : 
    2211      100610 :         while (YYCURSOR < YYLIMIT) {
    2212       84547 :                 switch (*YYCURSOR++) {
    2213             :                         case '"':
    2214        9452 :                                 break;
    2215             :                         case '$':
    2216        6386 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2217             :                                         break;
    2218             :                                 }
    2219           1 :                                 continue;
    2220             :                         case '{':
    2221         245 :                                 if (*YYCURSOR == '$') {
    2222         226 :                                         break;
    2223             :                                 }
    2224          19 :                                 continue;
    2225             :                         case '\\':
    2226        5615 :                                 if (YYCURSOR < YYLIMIT) {
    2227        5615 :                                         YYCURSOR++;
    2228             :                                 }
    2229             :                                 /* fall through */
    2230             :                         default:
    2231       68464 :                                 continue;
    2232             :                 }
    2233             : 
    2234       16063 :                 YYCURSOR--;
    2235       16063 :                 break;
    2236             :         }
    2237             : 
    2238             : double_quotes_scan_done:
    2239       26015 :         yyleng = YYCURSOR - SCNG(yy_text);
    2240             : 
    2241       26015 :         zend_scan_escape_string(zendlval, yytext, yyleng, '"' TSRMLS_CC);
    2242       26015 :         return T_ENCAPSED_AND_WHITESPACE;
    2243             : }
    2244             : 
    2245             : 
    2246             : <ST_BACKQUOTE>{ANY_CHAR} {
    2247         172 :         if (YYCURSOR > YYLIMIT) {
    2248           0 :                 return 0;
    2249             :         }
    2250         172 :         if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
    2251           0 :                 YYCURSOR++;
    2252             :         }
    2253             : 
    2254        2601 :         while (YYCURSOR < YYLIMIT) {
    2255        2429 :                 switch (*YYCURSOR++) {
    2256             :                         case '`':
    2257          96 :                                 break;
    2258             :                         case '$':
    2259          76 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2260             :                                         break;
    2261             :                                 }
    2262           0 :                                 continue;
    2263             :                         case '{':
    2264           4 :                                 if (*YYCURSOR == '$') {
    2265           0 :                                         break;
    2266             :                                 }
    2267           4 :                                 continue;
    2268             :                         case '\\':
    2269           6 :                                 if (YYCURSOR < YYLIMIT) {
    2270           6 :                                         YYCURSOR++;
    2271             :                                 }
    2272             :                                 /* fall through */
    2273             :                         default:
    2274        2253 :                                 continue;
    2275             :                 }
    2276             : 
    2277         172 :                 YYCURSOR--;
    2278         172 :                 break;
    2279             :         }
    2280             : 
    2281         172 :         yyleng = YYCURSOR - SCNG(yy_text);
    2282             : 
    2283         172 :         zend_scan_escape_string(zendlval, yytext, yyleng, '`' TSRMLS_CC);
    2284         172 :         return T_ENCAPSED_AND_WHITESPACE;
    2285             : }
    2286             : 
    2287             : 
    2288             : <ST_HEREDOC>{ANY_CHAR} {
    2289        1874 :         int newline = 0;
    2290             : 
    2291        1874 :         if (YYCURSOR > YYLIMIT) {
    2292           1 :                 return 0;
    2293             :         }
    2294             : 
    2295        1873 :         YYCURSOR--;
    2296             : 
    2297      325753 :         while (YYCURSOR < YYLIMIT) {
    2298      323879 :                 switch (*YYCURSOR++) {
    2299             :                         case '\r':
    2300           0 :                                 if (*YYCURSOR == '\n') {
    2301           0 :                                         YYCURSOR++;
    2302             :                                 }
    2303             :                                 /* fall through */
    2304             :                         case '\n':
    2305             :                                 /* Check for ending label on the next line */
    2306        9777 :                                 if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
    2307        1375 :                                         YYCTYPE *end = YYCURSOR + CG(heredoc_len);
    2308             : 
    2309        1375 :                                         if (*end == ';') {
    2310        1316 :                                                 end++;
    2311             :                                         }
    2312             : 
    2313        1375 :                                         if (*end == '\n' || *end == '\r') {
    2314             :                                                 /* newline before label will be subtracted from returned text, but
    2315             :                                                  * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */
    2316        1371 :                                                 if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') {
    2317           0 :                                                         newline = 2; /* Windows newline */
    2318             :                                                 } else {
    2319        1371 :                                                         newline = 1;
    2320             :                                                 }
    2321             : 
    2322        1371 :                                                 CG(increment_lineno) = 1; /* For newline before label */
    2323        1371 :                                                 BEGIN(ST_END_HEREDOC);
    2324             : 
    2325        1371 :                                                 goto heredoc_scan_done;
    2326             :                                         }
    2327             :                                 }
    2328        8406 :                                 continue;
    2329             :                         case '$':
    2330         524 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2331             :                                         break;
    2332             :                                 }
    2333          79 :                                 continue;
    2334             :                         case '{':
    2335          81 :                                 if (*YYCURSOR == '$') {
    2336          56 :                                         break;
    2337             :                                 }
    2338          25 :                                 continue;
    2339             :                         case '\\':
    2340         617 :                                 if (YYCURSOR < YYLIMIT && *YYCURSOR != '\n' && *YYCURSOR != '\r') {
    2341         609 :                                         YYCURSOR++;
    2342             :                                 }
    2343             :                                 /* fall through */
    2344             :                         default:
    2345      313497 :                                 continue;
    2346             :                 }
    2347             : 
    2348         501 :                 YYCURSOR--;
    2349         501 :                 break;
    2350             :         }
    2351             : 
    2352             : heredoc_scan_done:
    2353        1873 :         yyleng = YYCURSOR - SCNG(yy_text);
    2354             : 
    2355        1873 :         zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0 TSRMLS_CC);
    2356        1873 :         return T_ENCAPSED_AND_WHITESPACE;
    2357             : }
    2358             : 
    2359             : 
    2360             : <ST_NOWDOC>{ANY_CHAR} {
    2361          46 :         int newline = 0;
    2362             : 
    2363          46 :         if (YYCURSOR > YYLIMIT) {
    2364           0 :                 return 0;
    2365             :         }
    2366             : 
    2367          46 :         YYCURSOR--;
    2368             : 
    2369        2508 :         while (YYCURSOR < YYLIMIT) {
    2370        2462 :                 switch (*YYCURSOR++) {
    2371             :                         case '\r':
    2372           0 :                                 if (*YYCURSOR == '\n') {
    2373           0 :                                         YYCURSOR++;
    2374             :                                 }
    2375             :                                 /* fall through */
    2376             :                         case '\n':
    2377             :                                 /* Check for ending label on the next line */
    2378         138 :                                 if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
    2379          51 :                                         YYCTYPE *end = YYCURSOR + CG(heredoc_len);
    2380             : 
    2381          51 :                                         if (*end == ';') {
    2382          33 :                                                 end++;
    2383             :                                         }
    2384             : 
    2385          51 :                                         if (*end == '\n' || *end == '\r') {
    2386             :                                                 /* newline before label will be subtracted from returned text, but
    2387             :                                                  * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */
    2388          46 :                                                 if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') {
    2389           0 :                                                         newline = 2; /* Windows newline */
    2390             :                                                 } else {
    2391          46 :                                                         newline = 1;
    2392             :                                                 }
    2393             : 
    2394          46 :                                                 CG(increment_lineno) = 1; /* For newline before label */
    2395          46 :                                                 BEGIN(ST_END_HEREDOC);
    2396             : 
    2397          46 :                                                 goto nowdoc_scan_done;
    2398             :                                         }
    2399             :                                 }
    2400             :                                 /* fall through */
    2401             :                         default:
    2402        2416 :                                 continue;
    2403             :                 }
    2404             :         }
    2405             : 
    2406             : nowdoc_scan_done:
    2407          46 :         yyleng = YYCURSOR - SCNG(yy_text);
    2408             : 
    2409          46 :         zend_copy_value(zendlval, yytext, yyleng - newline);
    2410          46 :         zendlval->type = IS_STRING;
    2411          46 :         HANDLE_NEWLINES(yytext, yyleng - newline);
    2412          46 :         return T_ENCAPSED_AND_WHITESPACE;
    2413             : }
    2414             : 
    2415             : 
    2416             : <ST_IN_SCRIPTING,ST_VAR_OFFSET>{ANY_CHAR} {
    2417        2310 :         if (YYCURSOR > YYLIMIT) {
    2418        2310 :                 return 0;
    2419             :         }
    2420             : 
    2421           0 :         zend_error(E_COMPILE_WARNING,"Unexpected character in input:  '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
    2422           0 :         goto restart;
    2423             : }
    2424             : 
    2425             : */
    2426             : }

Generated by: LCOV version 1.10

Generated at Thu, 16 Oct 2014 05:27:14 +0000 (4 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.