Skip to content

Commit f7556db

Browse files
committed
Support more parse state
1 parent 961552d commit f7556db

14 files changed

+66
-28
lines changed

Zend/zend_compile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static inline uint32_t zend_alloc_cache_slot(void) {
8080
}
8181

8282
ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);
83-
ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename, bool begin_initial);
83+
ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename, zend_lex_begin_state begin_state);
8484

8585
#ifndef ZTS
8686
ZEND_API zend_compiler_globals compiler_globals;

Zend/zend_compile.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,12 @@ struct _zend_execute_data {
740740

741741
#include "zend_globals.h"
742742

743+
typedef enum _zend_lex_begin_state {
744+
ZEND_LEX_BEGIN_STATE_SHEBANG = 0,
745+
ZEND_LEX_BEGIN_STATE_INITIAL,
746+
ZEND_LEX_BEGIN_STATE_ST_IN_SCRIPTING
747+
} zend_lex_begin_state;
748+
743749
BEGIN_EXTERN_C()
744750

745751
void init_compiler(void);
@@ -752,7 +758,7 @@ void zend_file_context_begin(zend_file_context *prev_context);
752758
void zend_file_context_end(zend_file_context *prev_context);
753759

754760
extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);
755-
extern ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename, bool begin_initial);
761+
extern ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename, zend_lex_begin_state begin_state);
756762

757763
ZEND_API int ZEND_FASTCALL lex_scan(zval *zendlval, zend_parser_stack_elem *elem);
758764
void startup_scanner(void);
@@ -807,7 +813,7 @@ zend_string *zval_make_interned_string(zval *zv);
807813
struct _zend_arena;
808814

809815
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type);
810-
ZEND_API zend_op_array *compile_string(zend_string *source_string, const char *filename, bool begin_initial);
816+
ZEND_API zend_op_array *compile_string(zend_string *source_string, const char *filename, zend_lex_begin_state begin_state);
811817
ZEND_API zend_op_array *compile_filename(int type, zend_string *filename);
812818
ZEND_API zend_ast *zend_compile_string_to_ast(
813819
zend_string *code, struct _zend_arena **ast_arena, zend_string *filename);

Zend/zend_execute.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4405,7 +4405,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
44054405
break;
44064406
case ZEND_EVAL: {
44074407
char *eval_desc = zend_make_compiled_string_description("eval()'d code");
4408-
new_op_array = zend_compile_string(inc_filename, eval_desc, 0);
4408+
new_op_array = zend_compile_string(inc_filename, eval_desc, ZEND_LEX_BEGIN_STATE_ST_IN_SCRIPTING);
44094409
efree(eval_desc);
44104410
}
44114411
break;

Zend/zend_execute_API.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ ZEND_API zend_result zend_eval_stringl(const char *str, size_t str_len, zval *re
12231223

12241224
original_compiler_options = CG(compiler_options);
12251225
CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
1226-
new_op_array = zend_compile_string(code_str, string_name, 0);
1226+
new_op_array = zend_compile_string(code_str, string_name, ZEND_LEX_BEGIN_STATE_ST_IN_SCRIPTING);
12271227
CG(compiler_options) = original_compiler_options;
12281228

12291229
if (new_op_array) {

Zend/zend_language_scanner.l

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ ZEND_API size_t zend_get_scanned_file_offset(void)
782782
return offset;
783783
}
784784

785-
zend_op_array *compile_string(zend_string *source_string, const char *filename, bool begin_initial)
785+
zend_op_array *compile_string(zend_string *source_string, const char *filename, zend_lex_begin_state begin_state)
786786
{
787787
zend_lex_state original_lex_state;
788788
zend_op_array *op_array = NULL;
@@ -799,11 +799,19 @@ zend_op_array *compile_string(zend_string *source_string, const char *filename,
799799
filename_str = zend_string_init(filename, strlen(filename), 0);
800800
zend_prepare_string_for_scanning(&tmp, filename_str);
801801
zend_string_release(filename_str);
802-
if (begin_initial) {
803-
BEGIN(INITIAL);
804-
} else {
805-
BEGIN(ST_IN_SCRIPTING);
802+
803+
switch (begin_state) {
804+
case ZEND_LEX_BEGIN_STATE_SHEBANG:
805+
BEGIN(SHEBANG);
806+
break;
807+
case ZEND_LEX_BEGIN_STATE_INITIAL:
808+
BEGIN(INITIAL);
809+
break;
810+
case ZEND_LEX_BEGIN_STATE_ST_IN_SCRIPTING:
811+
BEGIN(ST_IN_SCRIPTING);
812+
break;
806813
}
814+
807815
op_array = zend_compile(ZEND_EVAL_CODE);
808816

809817
zend_restore_lexical_state(&original_lex_state);

ext/zend_test/test.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,17 +203,17 @@ static ZEND_FUNCTION(zend_test_compile_string)
203203
{
204204
zend_string *source_string = NULL;
205205
zend_string *filename = NULL;
206-
bool begin_initial = 0;
206+
zend_long begin_state = ZEND_LEX_BEGIN_STATE_INITIAL;
207207

208208
ZEND_PARSE_PARAMETERS_START(3, 3)
209209
Z_PARAM_STR(source_string)
210210
Z_PARAM_STR(filename)
211-
Z_PARAM_BOOL(begin_initial)
211+
Z_PARAM_LONG(begin_state)
212212
ZEND_PARSE_PARAMETERS_END();
213213

214214
zend_op_array *op_array = NULL;
215215

216-
op_array = compile_string(source_string, ZSTR_VAL(filename), begin_initial);
216+
op_array = compile_string(source_string, ZSTR_VAL(filename), begin_state);
217217

218218
if (op_array) {
219219
zval retval;

ext/zend_test/test.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ function zend_test_nullable_array_return(): ?array {}
6262

6363
function zend_test_void_return(): void {}
6464

65-
function zend_test_compile_string(string $source_string, string $filename, bool $begin_initial): void {}
65+
function zend_test_compile_string(string $source_string, string $filename, int $begin_state): void {}
6666

6767
/** @deprecated */
6868
function zend_test_deprecated(mixed $arg = null): void {}

ext/zend_test/test_arginfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 7432f512564a359ecac72fb2cfc9718f5728166a */
2+
* Stub hash: 91ffc3205c6ac7b07953c9446e9cb9988d893dd4 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
55
ZEND_END_ARG_INFO()
@@ -13,7 +13,7 @@ ZEND_END_ARG_INFO()
1313
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_compile_string, 0, 3, IS_VOID, 0)
1414
ZEND_ARG_TYPE_INFO(0, source_string, IS_STRING, 0)
1515
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
16-
ZEND_ARG_TYPE_INFO(0, begin_initial, _IS_BOOL, 0)
16+
ZEND_ARG_TYPE_INFO(0, begin_state, IS_LONG, 0)
1717
ZEND_END_ARG_INFO()
1818

1919
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_deprecated, 0, 0, IS_VOID, 0)

ext/zend_test/tests/zend_test_compile_string.phpt

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,52 @@ Zend: Test compile string
44
zend_test
55
--FILE--
66
<?php
7+
8+
define('ZEND_LEX_BEGIN_STATE_SHEBANG', 0);
9+
define('ZEND_LEX_BEGIN_STATE_INITIAL', 1);
10+
define('ZEND_LEX_BEGIN_STATE_ST_IN_SCRIPTING', 2);
11+
12+
$source_string = <<<EOF
13+
#!/path/to/php
14+
<?php
15+
var_dump('php');
16+
EOF;
17+
18+
zend_test_compile_string($source_string, 'Source string', ZEND_LEX_BEGIN_STATE_SHEBANG);
19+
720
$source_string = <<<EOF
21+
#!/path/to/php
822
<?php
923
var_dump('php');
1024
EOF;
1125

12-
zend_test_compile_string($source_string, 'Source string', 1);
26+
zend_test_compile_string($source_string, 'Source string', ZEND_LEX_BEGIN_STATE_INITIAL);
27+
28+
$source_string = <<<EOF
29+
<?php
30+
var_dump('php');
31+
EOF;
32+
33+
zend_test_compile_string($source_string, 'Source string', ZEND_LEX_BEGIN_STATE_INITIAL);
1334

1435
$source_string = <<<EOF
1536
var_dump('php');
1637
EOF;
1738

18-
zend_test_compile_string($source_string, 'Source string', 0);
39+
zend_test_compile_string($source_string, 'Source string', ZEND_LEX_BEGIN_STATE_ST_IN_SCRIPTING);
1940

2041
$source_string = <<<EOF
2142
<?php
2243
var_dump('php');
2344
EOF;
2445

25-
zend_test_compile_string($source_string, 'Source string', 0);
46+
zend_test_compile_string($source_string, 'Source string', ZEND_LEX_BEGIN_STATE_ST_IN_SCRIPTING);
2647
?>
2748
--EXPECT--
2849
string(3) "php"
50+
#!/path/to/php
51+
string(3) "php"
52+
string(3) "php"
2953
string(3) "php"
3054

3155
Parse error: syntax error, unexpected token "<", expecting end of file in Source string on line 1

sapi/fuzzer/fuzzer-execute.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ static void fuzzer_execute_ex(zend_execute_data *execute_data) {
5050
}
5151
}
5252

53-
static zend_op_array *(*orig_compile_string)(zend_string *source_string, const char *filename, bool begin_initial);
53+
static zend_op_array *(*orig_compile_string)(zend_string *source_string, const char *filename, zend_lex_begin_state begin_state);
5454

55-
static zend_op_array *fuzzer_compile_string(zend_string *str, const char *filename, bool begin_initial) {
55+
static zend_op_array *fuzzer_compile_string(zend_string *str, const char *filename, bool begin_state) {
5656
if (ZSTR_LEN(str) > MAX_SIZE) {
5757
/* Avoid compiling huge inputs via eval(). */
5858
zend_bailout();
5959
}
6060

61-
return orig_compile_string(str, filename, begin_initial);
61+
return orig_compile_string(str, filename, begin_state);
6262
}
6363

6464
static void (*orig_execute_internal)(zend_execute_data *execute_data, zval *return_value);

0 commit comments

Comments
 (0)