diff options
Diffstat (limited to 'Zend/zend_language_scanner.l')
-rw-r--r-- | Zend/zend_language_scanner.l | 134 |
1 files changed, 92 insertions, 42 deletions
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 7e60f5cf05..6f2889aac8 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -307,20 +307,25 @@ ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle) } } -ZEND_API zend_result zend_lex_tstring(zval *zv, zend_lexer_ident_ref ident_ref) +ZEND_API zend_result zend_lex_tstring(zval *zv, unsigned char *ident) { - char *ident = (char *) SCNG(yy_start) + ident_ref.offset; - size_t length = ident_ref.len; - if (length == sizeof("<?=")-1 && memcmp(ident, "<?=", sizeof("<?=")-1) == 0) { + unsigned char *end = ident; + while ((*end >= 'a' && *end <= 'z') || (*end >= 'A' && *end <= 'Z') || *end == '_') { + end++; + } + + size_t length = end - ident; + if (length == 0) { + ZEND_ASSERT(ident[0] == '<' && ident[1] == '?' && ident[2] == '='); zend_throw_exception(zend_ce_parse_error, "Cannot use \"<?=\" as an identifier", 0); return FAILURE; } if (SCNG(on_event)) { - SCNG(on_event)(ON_FEEDBACK, T_STRING, 0, ident, length, SCNG(on_event_context)); + SCNG(on_event)(ON_FEEDBACK, T_STRING, 0, (char *) ident, length, SCNG(on_event_context)); } - ZVAL_STRINGL(zv, ident, length); + ZVAL_STRINGL(zv, (char *) ident, length); return SUCCESS; } @@ -601,7 +606,7 @@ END_EXTERN_C() static zend_op_array *zend_compile(int type) { zend_op_array *op_array = NULL; - zend_bool original_in_compilation = CG(in_compilation); + bool original_in_compilation = CG(in_compilation); CG(in_compilation) = 1; CG(ast) = NULL; @@ -669,9 +674,9 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type) } ZEND_API zend_ast *zend_compile_string_to_ast( - zend_string *code, zend_arena **ast_arena, const char *filename) { + zend_string *code, zend_arena **ast_arena, zend_string *filename) { zval code_zv; - zend_bool original_in_compilation; + bool original_in_compilation; zend_lex_state original_lex_state; zend_ast *ast; @@ -737,11 +742,10 @@ zend_op_array *compile_filename(int type, zval *filename) return retval; } -ZEND_API void zend_prepare_string_for_scanning(zval *str, const char *filename) +ZEND_API void zend_prepare_string_for_scanning(zval *str, zend_string *filename) { char *buf; size_t size, old_len; - zend_string *new_compiled_filename; /* enforce ZEND_MMAP_AHEAD trailing NULLs for flex... */ old_len = Z_STRLEN_P(str); @@ -773,10 +777,7 @@ ZEND_API void zend_prepare_string_for_scanning(zval *str, const char *filename) } yy_scan_buffer(buf, size); - - new_compiled_filename = zend_string_init(filename, strlen(filename), 0); - zend_set_compiled_filename(new_compiled_filename); - zend_string_release_ex(new_compiled_filename, 0); + zend_set_compiled_filename(filename); CG(zend_lineno) = 1; CG(increment_lineno) = 0; RESET_DOC_COMMENT(); @@ -809,6 +810,7 @@ zend_op_array *compile_string(zend_string *source_string, const char *filename) zend_lex_state original_lex_state; zend_op_array *op_array = NULL; zval tmp; + zend_string *filename_str; if (ZSTR_LEN(source_string) == 0) { return NULL; @@ -817,7 +819,9 @@ zend_op_array *compile_string(zend_string *source_string, const char *filename) ZVAL_STR_COPY(&tmp, source_string); zend_save_lexical_state(&original_lex_state); - zend_prepare_string_for_scanning(&tmp, filename); + filename_str = zend_string_init(filename, strlen(filename), 0); + zend_prepare_string_for_scanning(&tmp, filename_str); + zend_string_release(filename_str); BEGIN(ST_IN_SCRIPTING); op_array = zend_compile(ZEND_EVAL_CODE); @@ -851,17 +855,15 @@ zend_result highlight_file(const char *filename, zend_syntax_highlighter_ini *sy return SUCCESS; } -void highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, const char *str_name) +void highlight_string(zend_string *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, const char *filename) { zend_lex_state original_lex_state; - zval tmp; - - if (UNEXPECTED(Z_TYPE_P(str) != IS_STRING)) { - ZVAL_STR(&tmp, zval_get_string_func(str)); - str = &tmp; - } + zval str_zv; + zend_string *filename_str = zend_string_init(filename, strlen(filename), 0); + ZVAL_STR_COPY(&str_zv, str); zend_save_lexical_state(&original_lex_state); - zend_prepare_string_for_scanning(str, str_name); + zend_prepare_string_for_scanning(&str_zv, filename_str); + zend_string_release(filename_str); BEGIN(INITIAL); zend_highlight(syntax_highlighter_ini); if (SCNG(script_filtered)) { @@ -869,9 +871,7 @@ void highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter SCNG(script_filtered) = NULL; } zend_restore_lexical_state(&original_lex_state); - if (UNEXPECTED(str == &tmp)) { - zval_ptr_dtor(&tmp); - } + zval_ptr_dtor(&str_zv); } ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter, const zend_encoding *old_encoding) @@ -1023,7 +1023,7 @@ static zend_result zend_scan_escape_string(zval *zendlval, char *str, int len, c /* cache where we started so we can parse after validating */ char *start = s + 1; size_t len = 0; - zend_bool valid = 1; + bool valid = 1; unsigned long codepoint; if (*start != '{') { @@ -1163,9 +1163,9 @@ static const char *next_newline(const char *str, const char *end, size_t *newlin return NULL; } -static zend_bool strip_multiline_string_indentation( - zval *zendlval, int indentation, zend_bool using_spaces, - zend_bool newline_at_start, zend_bool newline_at_end) +static bool strip_multiline_string_indentation( + zval *zendlval, int indentation, bool using_spaces, + bool newline_at_start, bool newline_at_end) { const char *str = Z_STRVAL_P(zendlval), *end = str + Z_STRLEN_P(zendlval); char *copy = Z_STRVAL_P(zendlval); @@ -1372,6 +1372,7 @@ DNUM ({LNUM}?"."{LNUM})|({LNUM}"."{LNUM}?) EXPONENT_DNUM (({LNUM}|{DNUM})[eE][+-]?{LNUM}) HNUM "0x"[0-9a-fA-F]+(_[0-9a-fA-F]+)* BNUM "0b"[01]+(_[01]+)* +ONUM "0o"[0-7]+(_[0-7]+)* LABEL [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]* WHITESPACE [ \n\r\t]+ TABS_AND_SPACES [ \t]* @@ -1918,7 +1919,7 @@ NEWLINE ("\r"|"\n"|"\r\n") /* The +/- 2 skips "0b" */ size_t len = yyleng - 2; char *end, *bin = yytext + 2; - zend_bool contains_underscores; + bool contains_underscores; /* Skip any leading 0s */ while (len > 0 && (*bin == '0' || *bin == '_')) { @@ -1956,11 +1957,61 @@ NEWLINE ("\r"|"\n"|"\r\n") } } +<ST_IN_SCRIPTING>{ONUM} { + /* The +/- 2 skips "0o" */ + size_t len = yyleng - 2; + char *end, *octal = yytext + 2; + bool contains_underscores = (memchr(octal, '_', len) != NULL); + + /* Skip any leading 0s */ + while (len > 0 && (*octal == '0' || *octal == '_')) { + ++octal; + --len; + } + + if (len == 0) { + ZVAL_LONG(zendlval, 0); + RETURN_TOKEN_WITH_VAL(T_LNUMBER); + } + + if (contains_underscores) { + octal = estrndup(octal, len); + strip_underscores(octal, &len); + } + + errno = 0; + + ZVAL_LONG(zendlval, ZEND_STRTOL(octal, &end, 8)); + + ZEND_ASSERT(end == octal + len); + + if (!errno) { + if (contains_underscores) { + efree(octal); + } + RETURN_TOKEN_WITH_VAL(T_LNUMBER); + } + + /* Overflow */ + ZEND_ASSERT(errno == ERANGE); + /* Reset errno */ + errno = 0; + + /* zend_oct_strtod skips leading '0' */ + ZVAL_DOUBLE(zendlval, zend_oct_strtod(octal, (const char **)&end)); + ZEND_ASSERT(!errno); + ZEND_ASSERT(end == octal + len); + if (contains_underscores) { + efree(octal); + } + RETURN_TOKEN_WITH_VAL(T_DNUMBER); +} + <ST_IN_SCRIPTING>{LNUM} { size_t len = yyleng; char *end, *lnum = yytext; - zend_bool is_octal = lnum[0] == '0'; - zend_bool contains_underscores = (memchr(lnum, '_', len) != NULL); + bool is_octal = lnum[0] == '0'; + bool contains_underscores = (memchr(lnum, '_', len) != NULL); if (contains_underscores) { lnum = estrndup(lnum, len); @@ -2023,7 +2074,7 @@ NEWLINE ("\r"|"\n"|"\r\n") /* The +/- 2 skips "0x" */ size_t len = yyleng - 2; char *end, *hex = yytext + 2; - zend_bool contains_underscores; + bool contains_underscores; /* Skip any leading 0s */ while (len > 0 && (*hex == '0' || *hex == '_')) { @@ -2077,7 +2128,7 @@ string: RETURN_TOKEN_WITH_VAL(T_NUM_STRING); } -<ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM} { /* Offset must be treated as a string */ +<ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM}|{ONUM} { /* Offset must be treated as a string */ if (yyleng == 1) { ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR((zend_uchar)*(yytext))); } else { @@ -2090,7 +2141,7 @@ string: const char *end; size_t len = yyleng; char *dnum = yytext; - zend_bool contains_underscores = (memchr(dnum, '_', len) != NULL); + bool contains_underscores = (memchr(dnum, '_', len) != NULL); if (contains_underscores) { dnum = estrndup(dnum, len); @@ -2528,7 +2579,7 @@ skip_escape_conversion: unsigned char *saved_cursor; int bprefix = (yytext[0] != '<') ? 1 : 0, spacing = 0, indentation = 0; zend_heredoc_label *heredoc_label = emalloc(sizeof(zend_heredoc_label)); - zend_bool is_heredoc = 1; + bool is_heredoc = 1; CG(zend_lineno)++; heredoc_label->length = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0); @@ -2909,7 +2960,7 @@ heredoc_scan_done: ZVAL_STRINGL(zendlval, yytext, yyleng - newline); if (!SCNG(heredoc_scan_ahead) && !EG(exception) && PARSER_MODE()) { - zend_bool newline_at_start = *(yytext - 1) == '\n' || *(yytext - 1) == '\r'; + bool newline_at_start = *(yytext - 1) == '\n' || *(yytext - 1) == '\r'; zend_string *copy = Z_STR_P(zendlval); if (!strip_multiline_string_indentation( @@ -3010,7 +3061,7 @@ nowdoc_scan_done: ZVAL_STRINGL(zendlval, yytext, yyleng - newline); if (!EG(exception) && spacing != -1 && PARSER_MODE()) { - zend_bool newline_at_start = *(yytext - 1) == '\n' || *(yytext - 1) == '\r'; + bool newline_at_start = *(yytext - 1) == '\n' || *(yytext - 1) == '\r'; if (!strip_multiline_string_indentation( zendlval, indentation, spacing == HEREDOC_USING_SPACES, newline_at_start, newline != 0)) { @@ -3050,8 +3101,7 @@ emit_token: emit_token_with_ident: if (PARSER_MODE()) { - elem->ident.offset = SCNG(yy_text) - SCNG(yy_start); - elem->ident.len = SCNG(yy_leng); + elem->ident = SCNG(yy_text); } if (SCNG(on_event)) { SCNG(on_event)(ON_TOKEN, token, start_line, yytext, yyleng, SCNG(on_event_context)); |