Skip to content

Support compile_string passing parsing state #7462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static inline uint32_t zend_alloc_cache_slot(void) {
}

ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);
ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename);
ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename, zend_compile_position position);

#ifndef ZTS
ZEND_API zend_compiler_globals compiler_globals;
Expand Down
10 changes: 8 additions & 2 deletions Zend/zend_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,12 @@ struct _zend_execute_data {

#include "zend_globals.h"

typedef enum _zend_compile_position {
ZEND_COMPILE_POSITION_AT_SHEBANG = 0,
ZEND_COMPILE_POSITION_AT_OPEN_TAG,
ZEND_COMPILE_POSITION_AFTER_OPEN_TAG
} zend_compile_position;

BEGIN_EXTERN_C()

void init_compiler(void);
Expand All @@ -755,7 +761,7 @@ void zend_file_context_begin(zend_file_context *prev_context);
void zend_file_context_end(zend_file_context *prev_context);

extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);
extern ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename);
extern ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename, zend_compile_position position);

ZEND_API int ZEND_FASTCALL lex_scan(zval *zendlval, zend_parser_stack_elem *elem);
void startup_scanner(void);
Expand Down Expand Up @@ -810,7 +816,7 @@ zend_string *zval_make_interned_string(zval *zv);
struct _zend_arena;

ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type);
ZEND_API zend_op_array *compile_string(zend_string *source_string, const char *filename);
ZEND_API zend_op_array *compile_string(zend_string *source_string, const char *filename, zend_compile_position position);
ZEND_API zend_op_array *compile_filename(int type, zend_string *filename);
ZEND_API zend_ast *zend_compile_string_to_ast(
zend_string *code, struct _zend_arena **ast_arena, zend_string *filename);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -4394,7 +4394,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
break;
case ZEND_EVAL: {
char *eval_desc = zend_make_compiled_string_description("eval()'d code");
new_op_array = zend_compile_string(inc_filename, eval_desc);
new_op_array = zend_compile_string(inc_filename, eval_desc, ZEND_COMPILE_POSITION_AFTER_OPEN_TAG);
efree(eval_desc);
}
break;
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ ZEND_API zend_result zend_eval_stringl(const char *str, size_t str_len, zval *re

original_compiler_options = CG(compiler_options);
CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
new_op_array = zend_compile_string(code_str, string_name);
new_op_array = zend_compile_string(code_str, string_name, ZEND_COMPILE_POSITION_AFTER_OPEN_TAG);
CG(compiler_options) = original_compiler_options;

if (new_op_array) {
Expand Down
16 changes: 14 additions & 2 deletions Zend/zend_language_scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ ZEND_API size_t zend_get_scanned_file_offset(void)
return offset;
}

zend_op_array *compile_string(zend_string *source_string, const char *filename)
zend_op_array *compile_string(zend_string *source_string, const char *filename, zend_compile_position position)
{
zend_lex_state original_lex_state;
zend_op_array *op_array = NULL;
Expand All @@ -799,7 +799,19 @@ zend_op_array *compile_string(zend_string *source_string, const char *filename)
filename_str = zend_string_init(filename, strlen(filename), 0);
zend_prepare_string_for_scanning(&tmp, filename_str);
zend_string_release(filename_str);
BEGIN(ST_IN_SCRIPTING);

switch (position) {
case ZEND_COMPILE_POSITION_AT_SHEBANG:
BEGIN(SHEBANG);
break;
case ZEND_COMPILE_POSITION_AT_OPEN_TAG:
BEGIN(INITIAL);
break;
case ZEND_COMPILE_POSITION_AFTER_OPEN_TAG:
BEGIN(ST_IN_SCRIPTING);
break;
}

op_array = zend_compile(ZEND_EVAL_CODE);

zend_restore_lexical_state(&original_lex_state);
Expand Down
35 changes: 35 additions & 0 deletions ext/zend_test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,41 @@ static ZEND_FUNCTION(zend_string_or_stdclass)
}
}

static ZEND_FUNCTION(zend_test_compile_string)
{
zend_string *source_string = NULL;
zend_string *filename = NULL;
zend_long position = ZEND_COMPILE_POSITION_AT_OPEN_TAG;

ZEND_PARSE_PARAMETERS_START(3, 3)
Z_PARAM_STR(source_string)
Z_PARAM_STR(filename)
Z_PARAM_LONG(position)
ZEND_PARSE_PARAMETERS_END();

zend_op_array *op_array = NULL;

op_array = compile_string(source_string, ZSTR_VAL(filename), position);

if (op_array) {
zval retval;

zend_try {
ZVAL_UNDEF(&retval);
zend_execute(op_array, &retval);
} zend_catch {
destroy_op_array(op_array);
efree_size(op_array, sizeof(zend_op_array));
zend_bailout();
} zend_end_try();

destroy_op_array(op_array);
efree_size(op_array, sizeof(zend_op_array));
}

return;
}

/* Tests Z_PARAM_OBJ_OF_CLASS_OR_STR_OR_NULL */
static ZEND_FUNCTION(zend_string_or_stdclass_or_null)
{
Expand Down
2 changes: 2 additions & 0 deletions ext/zend_test/test.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ function zend_test_nullable_array_return(): ?array {}

function zend_test_void_return(): void {}

function zend_test_compile_string(string $source_string, string $filename, int $position): void {}

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

Expand Down
10 changes: 9 additions & 1 deletion ext/zend_test/test_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 53832c784e59195e8ef41710c1e4e778f396c99b */
* Stub hash: 91ffc3205c6ac7b07953c9446e9cb9988d893dd4 */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
Expand All @@ -10,6 +10,12 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_void_return, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_compile_string, 0, 3, IS_VOID, 0)
ZEND_ARG_TYPE_INFO(0, source_string, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, position, IS_LONG, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_deprecated, 0, 0, IS_VOID, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg, IS_MIXED, 0, "null")
ZEND_END_ARG_INFO()
Expand Down Expand Up @@ -84,6 +90,7 @@ ZEND_END_ARG_INFO()
static ZEND_FUNCTION(zend_test_array_return);
static ZEND_FUNCTION(zend_test_nullable_array_return);
static ZEND_FUNCTION(zend_test_void_return);
static ZEND_FUNCTION(zend_test_compile_string);
static ZEND_FUNCTION(zend_test_deprecated);
static ZEND_FUNCTION(zend_create_unterminated_string);
static ZEND_FUNCTION(zend_terminate_string);
Expand Down Expand Up @@ -111,6 +118,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(zend_test_array_return, arginfo_zend_test_array_return)
ZEND_FE(zend_test_nullable_array_return, arginfo_zend_test_nullable_array_return)
ZEND_FE(zend_test_void_return, arginfo_zend_test_void_return)
ZEND_FE(zend_test_compile_string, arginfo_zend_test_compile_string)
ZEND_DEP_FE(zend_test_deprecated, arginfo_zend_test_deprecated)
ZEND_FE(zend_create_unterminated_string, arginfo_zend_create_unterminated_string)
ZEND_FE(zend_terminate_string, arginfo_zend_terminate_string)
Expand Down
55 changes: 55 additions & 0 deletions ext/zend_test/tests/zend_test_compile_string.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
--TEST--
Zend: Test compile string
--EXTENSIONS--
zend_test
--FILE--
<?php

define('ZEND_COMPILE_POSITION_AT_SHEBANG', 0);
define('ZEND_COMPILE_POSITION_AT_OPEN_TAG', 1);
define('ZEND_COMPILE_POSITION_AFTER_OPEN_TAG', 2);

$source_string = <<<EOF
#!/path/to/php
<?php
var_dump('php');
EOF;

zend_test_compile_string($source_string, 'Source string', ZEND_COMPILE_POSITION_AT_SHEBANG);

$source_string = <<<EOF
#!/path/to/php
<?php
var_dump('php');
EOF;

zend_test_compile_string($source_string, 'Source string', ZEND_COMPILE_POSITION_AT_OPEN_TAG);

$source_string = <<<EOF
<?php
var_dump('php');
EOF;

zend_test_compile_string($source_string, 'Source string', ZEND_COMPILE_POSITION_AT_OPEN_TAG);

$source_string = <<<EOF
var_dump('php');
EOF;

zend_test_compile_string($source_string, 'Source string', ZEND_COMPILE_POSITION_AFTER_OPEN_TAG);

$source_string = <<<EOF
<?php
var_dump('php');
EOF;

zend_test_compile_string($source_string, 'Source string', ZEND_COMPILE_POSITION_AFTER_OPEN_TAG);
?>
--EXPECT--
string(3) "php"
#!/path/to/php
string(3) "php"
string(3) "php"
string(3) "php"

Parse error: syntax error, unexpected token "<", expecting end of file in Source string on line 1
2 changes: 1 addition & 1 deletion sapi/phpdbg/phpdbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)

zend_op_array *(*compile_file)(zend_file_handle *file_handle, int type);
zend_op_array *(*init_compile_file)(zend_file_handle *file_handle, int type);
zend_op_array *(*compile_string)(zend_string *source_string, const char *filename);
zend_op_array *(*compile_string)(zend_string *source_string, const char *filename, zend_compile_position position);
HashTable file_sources;

zend_arena *oplog_arena; /* arena for storing oplog */
Expand Down
2 changes: 1 addition & 1 deletion sapi/phpdbg/phpdbg_bp.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co

bp_code = zend_string_concat3(
"return ", sizeof("return ")-1, expr, expr_len, ";", sizeof(";")-1);
new_break.ops = zend_compile_string(bp_code, "Conditional Breakpoint Code");
new_break.ops = zend_compile_string(bp_code, "Conditional Breakpoint Code", ZEND_COMPILE_POSITION_AFTER_OPEN_TAG);
zend_string_release(bp_code);

if (new_break.ops) {
Expand Down
6 changes: 3 additions & 3 deletions sapi/phpdbg/phpdbg_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,15 +309,15 @@ zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) {
return op_array;
}

zend_op_array *phpdbg_compile_string(zend_string *source_string, const char *filename) {
zend_op_array *phpdbg_compile_string(zend_string *source_string, const char *filename, zend_compile_position position) {
zend_string *fake_name;
zend_op_array *op_array;
phpdbg_file_source *dataptr;
uint32_t line;
char *bufptr, *endptr;

if (PHPDBG_G(flags) & PHPDBG_IN_EVAL) {
return PHPDBG_G(compile_string)(source_string, filename);
return PHPDBG_G(compile_string)(source_string, filename, position);
}

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

op_array = PHPDBG_G(compile_string)(source_string, filename);
op_array = PHPDBG_G(compile_string)(source_string, filename, position);

if (op_array == NULL) {
efree(dataptr->buf);
Expand Down
2 changes: 1 addition & 1 deletion sapi/phpdbg/phpdbg_prompt.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ PHPDBG_COMMAND(stdin)
} /* }}} */

int phpdbg_compile_stdin(zend_string *code) {
PHPDBG_G(ops) = zend_compile_string(code, "Standard input code");
PHPDBG_G(ops) = zend_compile_string(code, "Standard input code", ZEND_COMPILE_POSITION_AFTER_OPEN_TAG);
zend_string_release(code);

if (EG(exception)) {
Expand Down