diff options
-rw-r--r-- | Zend/tests/halt01.phpt | 12 | ||||
-rw-r--r-- | Zend/tests/halt02.phpt | 13 | ||||
-rw-r--r-- | Zend/tests/halt03.phpt | 10 | ||||
-rw-r--r-- | Zend/zend_compile.h | 1 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 5 | ||||
-rw-r--r-- | Zend/zend_language_scanner.l | 18 | ||||
-rw-r--r-- | Zend/zend_stream.c | 12 | ||||
-rw-r--r-- | Zend/zend_stream.h | 3 |
8 files changed, 73 insertions, 1 deletions
diff --git a/Zend/tests/halt01.phpt b/Zend/tests/halt01.phpt new file mode 100644 index 0000000000..3af80d07a8 --- /dev/null +++ b/Zend/tests/halt01.phpt @@ -0,0 +1,12 @@ +--TEST-- +__HALT_COMPILER() basic test +--FILE-- +<?php + +print "yo!\n"; + +__HALT_COMPILER(); + +none of this should be displayed! +--EXPECT-- +yo! diff --git a/Zend/tests/halt02.phpt b/Zend/tests/halt02.phpt new file mode 100644 index 0000000000..caaa474095 --- /dev/null +++ b/Zend/tests/halt02.phpt @@ -0,0 +1,13 @@ +--TEST-- +__HALT_COMPILER() basic test +--FILE-- +<?php + +$fp = fopen(__FILE__, "r"); +fseek($fp, __COMPILER_HALT_OFFSET__+1); +print fread($fp, 1000); + +__HALT_COMPILER(); +Overlay information... +--EXPECT-- +Overlay information... diff --git a/Zend/tests/halt03.phpt b/Zend/tests/halt03.phpt new file mode 100644 index 0000000000..6e0931b02f --- /dev/null +++ b/Zend/tests/halt03.phpt @@ -0,0 +1,10 @@ +--TEST-- +__HALT_COMPILER() basic test +--FILE-- +<?php + +if (true) { + __HALT_COMPILER(); +} +--EXPECTF-- +Fatal error: __HALT_COMPILER() can only be used from the outermost scope in %shalt03.php on line %d diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index ab0f470999..b5ae12ebca 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -321,6 +321,7 @@ ZEND_API char *zend_set_compiled_filename(char *new_compiled_filename TSRMLS_DC) ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC); ZEND_API char *zend_get_compiled_filename(TSRMLS_D); ZEND_API int zend_get_compiled_lineno(TSRMLS_D); +ZEND_API int zend_get_scanned_file_offset(TSRMLS_D); ZEND_API char* zend_get_compiled_variable_name(zend_op_array *op_array, zend_uint var, int* name_len); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 7fffd7e9cf..b5cf6ae9fe 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -35,6 +35,8 @@ #include "zend_list.h" #include "zend_globals.h" #include "zend_API.h" +#include "zend_constants.h" + #define YYERROR_VERBOSE #define YYSTYPE znode @@ -118,6 +120,7 @@ %token T_UNSET %token T_ISSET %token T_EMPTY +%token T_HALT_COMPILER %token T_CLASS %token T_INTERFACE %token T_EXTENDS @@ -159,6 +162,7 @@ top_statement: statement | function_declaration_statement { zend_do_early_binding(TSRMLS_C); } | class_declaration_statement { zend_do_early_binding(TSRMLS_C); } + | T_HALT_COMPILER '(' ')' ';' { REGISTER_MAIN_LONG_CONSTANT("__COMPILER_HALT_OFFSET__", zend_get_scanned_file_offset(TSRMLS_C), CONST_CS); YYACCEPT; } ; @@ -172,6 +176,7 @@ inner_statement: statement | function_declaration_statement | class_declaration_statement + | T_HALT_COMPILER '(' ')' ';' { zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); } ; diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 4482214082..7cd266fd39 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -494,6 +494,20 @@ ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_D } +ZEND_API int zend_get_scanned_file_offset(TSRMLS_D) +{ + if (yyin) { + int offset_in_buffer = (yy_c_buf_p - (YY_CURRENT_BUFFER)->yy_ch_buf); + int read_bytes = (YY_CURRENT_BUFFER)->yy_n_chars; + int offset_from_the_end = read_bytes - offset_in_buffer; + + return zend_stream_ftell(yyin TSRMLS_CC) - offset_from_the_end; + } else { + return -1; + } +} + + zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC) { zend_lex_state original_lex_state; @@ -1015,6 +1029,10 @@ NEWLINE ("\r"|"\n"|"\r\n") return T_EMPTY; } +<ST_IN_SCRIPTING>"__halt_compiler" { + return T_HALT_COMPILER; +} + <ST_IN_SCRIPTING>"static" { return T_STATIC; } diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c index bf68081b46..95050d3d26 100644 --- a/Zend/zend_stream.c +++ b/Zend/zend_stream.c @@ -35,6 +35,12 @@ static void zend_stream_stdio_closer(void *handle TSRMLS_DC) fclose((FILE*)handle); } +static long zend_stream_stdio_fteller(void *handle TSRMLS_DC) +{ + return ftell((FILE*) handle); +} + + ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC) { if (zend_stream_open_function) { @@ -83,6 +89,7 @@ ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC) file_handle->handle.stream.handle = file_handle->handle.fp; file_handle->handle.stream.reader = zend_stream_stdio_reader; file_handle->handle.stream.closer = zend_stream_stdio_closer; + file_handle->handle.stream.fteller = zend_stream_stdio_fteller; file_handle->handle.stream.interactive = isatty(fileno((FILE *)file_handle->handle.stream.handle)); } @@ -120,4 +127,7 @@ ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC) return 0; } - +ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC) +{ + return file_handle->handle.stream.fteller(file_handle->handle.stream.handle TSRMLS_CC); +} diff --git a/Zend/zend_stream.h b/Zend/zend_stream.h index c3d0ee1281..6633f5923d 100644 --- a/Zend/zend_stream.h +++ b/Zend/zend_stream.h @@ -27,11 +27,13 @@ typedef size_t (*zend_stream_reader_t)(void *handle, char *buf, size_t len TSRMLS_DC); typedef void (*zend_stream_closer_t)(void *handle TSRMLS_DC); +typedef long (*zend_stream_fteller_t)(void *handle TSRMLS_DC); typedef struct _zend_stream { void *handle; zend_stream_reader_t reader; zend_stream_closer_t closer; + zend_stream_fteller_t fteller; int interactive; } zend_stream; @@ -52,6 +54,7 @@ ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSR ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC); ZEND_API int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC); ZEND_API size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC); +ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC); ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC); END_EXTERN_C() |