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);

sapi/phpdbg/phpdbg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
270270

271271
zend_op_array *(*compile_file)(zend_file_handle *file_handle, int type);
272272
zend_op_array *(*init_compile_file)(zend_file_handle *file_handle, int type);
273-
zend_op_array *(*compile_string)(zend_string *source_string, const char *filename, bool begin_initial);
273+
zend_op_array *(*compile_string)(zend_string *source_string, const char *filename, zend_lex_begin_state begin_state);
274274
HashTable file_sources;
275275

276276
zend_arena *oplog_arena; /* arena for storing oplog */

sapi/phpdbg/phpdbg_bp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co
878878

879879
bp_code = zend_string_concat3(
880880
"return ", sizeof("return ")-1, expr, expr_len, ";", sizeof(";")-1);
881-
new_break.ops = zend_compile_string(bp_code, "Conditional Breakpoint Code", 0);
881+
new_break.ops = zend_compile_string(bp_code, "Conditional Breakpoint Code", ZEND_LEX_BEGIN_STATE_ST_IN_SCRIPTING);
882882
zend_string_release(bp_code);
883883

884884
if (new_break.ops) {

sapi/phpdbg/phpdbg_list.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,15 +309,15 @@ zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) {
309309
return op_array;
310310
}
311311

312-
zend_op_array *phpdbg_compile_string(zend_string *source_string, const char *filename, bool begin_initial) {
312+
zend_op_array *phpdbg_compile_string(zend_string *source_string, const char *filename, zend_lex_begin_state begin_state) {
313313
zend_string *fake_name;
314314
zend_op_array *op_array;
315315
phpdbg_file_source *dataptr;
316316
uint32_t line;
317317
char *bufptr, *endptr;
318318

319319
if (PHPDBG_G(flags) & PHPDBG_IN_EVAL) {
320-
return PHPDBG_G(compile_string)(source_string, filename, begin_initial);
320+
return PHPDBG_G(compile_string)(source_string, filename, begin_state);
321321
}
322322

323323
dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint32_t) * ZSTR_LEN(source_string));
@@ -332,7 +332,7 @@ zend_op_array *phpdbg_compile_string(zend_string *source_string, const char *fil
332332
dataptr->lines = ++line;
333333
dataptr->line[line] = endptr - dataptr->buf;
334334

335-
op_array = PHPDBG_G(compile_string)(source_string, filename, begin_initial);
335+
op_array = PHPDBG_G(compile_string)(source_string, filename, begin_state);
336336

337337
if (op_array == NULL) {
338338
efree(dataptr->buf);

sapi/phpdbg/phpdbg_prompt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ PHPDBG_COMMAND(stdin)
514514
} /* }}} */
515515

516516
int phpdbg_compile_stdin(zend_string *code) {
517-
PHPDBG_G(ops) = zend_compile_string(code, "Standard input code", 0);
517+
PHPDBG_G(ops) = zend_compile_string(code, "Standard input code", ZEND_LEX_BEGIN_STATE_ST_IN_SCRIPTING);
518518
zend_string_release(code);
519519

520520
if (EG(exception)) {

0 commit comments

Comments
 (0)