summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/tests/halt01.phpt12
-rw-r--r--Zend/tests/halt02.phpt13
-rw-r--r--Zend/tests/halt03.phpt10
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_language_parser.y5
-rw-r--r--Zend/zend_language_scanner.l18
-rw-r--r--Zend/zend_stream.c12
-rw-r--r--Zend/zend_stream.h3
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()