Skip to content

Commit d33500e

Browse files
committed
Thought I committed it ages ago... Anyway, without further delays, the final
__halt_compiler() patch
1 parent 09c2da0 commit d33500e

8 files changed

+73
-1
lines changed

Zend/tests/halt01.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
__HALT_COMPILER() basic test
3+
--FILE--
4+
<?php
5+
6+
print "yo!\n";
7+
8+
__HALT_COMPILER();
9+
10+
none of this should be displayed!
11+
--EXPECT--
12+
yo!

Zend/tests/halt02.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
__HALT_COMPILER() basic test
3+
--FILE--
4+
<?php
5+
6+
$fp = fopen(__FILE__, "r");
7+
fseek($fp, __COMPILER_HALT_OFFSET__+1);
8+
print fread($fp, 1000);
9+
10+
__HALT_COMPILER();
11+
Overlay information...
12+
--EXPECT--
13+
Overlay information...

Zend/tests/halt03.phpt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
__HALT_COMPILER() basic test
3+
--FILE--
4+
<?php
5+
6+
if (true) {
7+
__HALT_COMPILER();
8+
}
9+
--EXPECTF--
10+
Fatal error: __HALT_COMPILER() can only be used from the outermost scope in %shalt03.php on line %d

Zend/zend_compile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ ZEND_API char *zend_set_compiled_filename(char *new_compiled_filename TSRMLS_DC)
321321
ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC);
322322
ZEND_API char *zend_get_compiled_filename(TSRMLS_D);
323323
ZEND_API int zend_get_compiled_lineno(TSRMLS_D);
324+
ZEND_API int zend_get_scanned_file_offset(TSRMLS_D);
324325

325326
ZEND_API char* zend_get_compiled_variable_name(zend_op_array *op_array, zend_uint var, int* name_len);
326327

Zend/zend_language_parser.y

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include "zend_list.h"
3636
#include "zend_globals.h"
3737
#include "zend_API.h"
38+
#include "zend_constants.h"
39+
3840

3941
#define YYERROR_VERBOSE
4042
#define YYSTYPE znode
@@ -118,6 +120,7 @@
118120
%token T_UNSET
119121
%token T_ISSET
120122
%token T_EMPTY
123+
%token T_HALT_COMPILER
121124
%token T_CLASS
122125
%token T_INTERFACE
123126
%token T_EXTENDS
@@ -159,6 +162,7 @@ top_statement:
159162
statement
160163
| function_declaration_statement { zend_do_early_binding(TSRMLS_C); }
161164
| class_declaration_statement { zend_do_early_binding(TSRMLS_C); }
165+
| T_HALT_COMPILER '(' ')' ';' { REGISTER_MAIN_LONG_CONSTANT("__COMPILER_HALT_OFFSET__", zend_get_scanned_file_offset(TSRMLS_C), CONST_CS); YYACCEPT; }
162166
;
163167

164168

@@ -172,6 +176,7 @@ inner_statement:
172176
statement
173177
| function_declaration_statement
174178
| class_declaration_statement
179+
| T_HALT_COMPILER '(' ')' ';' { zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); }
175180
;
176181

177182

Zend/zend_language_scanner.l

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,20 @@ ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_D
494494
}
495495

496496

497+
ZEND_API int zend_get_scanned_file_offset(TSRMLS_D)
498+
{
499+
if (yyin) {
500+
int offset_in_buffer = (yy_c_buf_p - (YY_CURRENT_BUFFER)->yy_ch_buf);
501+
int read_bytes = (YY_CURRENT_BUFFER)->yy_n_chars;
502+
int offset_from_the_end = read_bytes - offset_in_buffer;
503+
504+
return zend_stream_ftell(yyin TSRMLS_CC) - offset_from_the_end;
505+
} else {
506+
return -1;
507+
}
508+
}
509+
510+
497511
zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
498512
{
499513
zend_lex_state original_lex_state;
@@ -1015,6 +1029,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
10151029
return T_EMPTY;
10161030
}
10171031
1032+
<ST_IN_SCRIPTING>"__halt_compiler" {
1033+
return T_HALT_COMPILER;
1034+
}
1035+
10181036
<ST_IN_SCRIPTING>"static" {
10191037
return T_STATIC;
10201038
}

Zend/zend_stream.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ static void zend_stream_stdio_closer(void *handle TSRMLS_DC)
3535
fclose((FILE*)handle);
3636
}
3737

38+
static long zend_stream_stdio_fteller(void *handle TSRMLS_DC)
39+
{
40+
return ftell((FILE*) handle);
41+
}
42+
43+
3844
ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC)
3945
{
4046
if (zend_stream_open_function) {
@@ -83,6 +89,7 @@ ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC)
8389
file_handle->handle.stream.handle = file_handle->handle.fp;
8490
file_handle->handle.stream.reader = zend_stream_stdio_reader;
8591
file_handle->handle.stream.closer = zend_stream_stdio_closer;
92+
file_handle->handle.stream.fteller = zend_stream_stdio_fteller;
8693

8794
file_handle->handle.stream.interactive = isatty(fileno((FILE *)file_handle->handle.stream.handle));
8895
}
@@ -120,4 +127,7 @@ ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC)
120127
return 0;
121128
}
122129

123-
130+
ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC)
131+
{
132+
return file_handle->handle.stream.fteller(file_handle->handle.stream.handle TSRMLS_CC);
133+
}

Zend/zend_stream.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727

2828
typedef size_t (*zend_stream_reader_t)(void *handle, char *buf, size_t len TSRMLS_DC);
2929
typedef void (*zend_stream_closer_t)(void *handle TSRMLS_DC);
30+
typedef long (*zend_stream_fteller_t)(void *handle TSRMLS_DC);
3031

3132
typedef struct _zend_stream {
3233
void *handle;
3334
zend_stream_reader_t reader;
3435
zend_stream_closer_t closer;
36+
zend_stream_fteller_t fteller;
3537
int interactive;
3638
} zend_stream;
3739

@@ -52,6 +54,7 @@ ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSR
5254
ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC);
5355
ZEND_API int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC);
5456
ZEND_API size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC);
57+
ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC);
5558
ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC);
5659
END_EXTERN_C()
5760

0 commit comments

Comments
 (0)