Skip to content

Commit ff5793a

Browse files
committed
Merge branch 'master' into jit-dynasm
* master: Turn interactive mode on, if cli binary is clicked in filemanager Fixed copy-paste mistake Added ZEND_GET_CLASS, ZEMD_GET_CALLED_CLASS, ZEND_GET_TYPE instructions, to implement corresponding builtin functions. Added a test case for (docs) bug #74652 Fixed test (backtrace was changed) Added ZEND_COUNT instruction, to implement corresponding builtin. "Countable" interface is moved from SPL to Core Fixed ZEND_IN_ARRAY related issues Improved UTF-8 validation in JSON Remove `user=foo` from FPM test config Skip FPM tests when running as root (unless requested)
2 parents 814350b + e5c273d commit ff5793a

29 files changed

+1107
-184
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ PHP NEWS
33
?? ??? ????, PHP 7.2
44

55
- Core:
6+
. Added ZEND_COUNT, ZEND_GET_CLASS, ZEMD_GET_CALLED_CLASS, ZEND_GET_TYPE
7+
instructions, to implement corresponding builtin functions. (Dmitry)
8+
. "Countable" interface is moved from SPL to Core. (Dmitry)
69
. Added ZEND_IN_ARRAY instruction, implementing optimized in_array() builtin
710
function, through hash lookup in flipped array. (Dmitry)
811
. Removed IS_TYPE_IMMUTABLE (it's the same as COPYABLE & !REFCOUNTED). (Dmitry)

Zend/zend_API.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,36 @@ ZEND_API char *zend_zval_type_name(const zval *arg) /* {{{ */
202202
}
203203
/* }}} */
204204

205+
ZEND_API zend_string *zend_zval_get_type(const zval *arg) /* {{{ */
206+
{
207+
switch (Z_TYPE_P(arg)) {
208+
case IS_NULL:
209+
return ZSTR_KNOWN(ZEND_STR_NULL);
210+
case IS_FALSE:
211+
case IS_TRUE:
212+
return ZSTR_KNOWN(ZEND_STR_BOOLEAN);
213+
case IS_LONG:
214+
return ZSTR_KNOWN(ZEND_STR_INTEGER);
215+
case IS_DOUBLE:
216+
return ZSTR_KNOWN(ZEND_STR_DOUBLE);
217+
case IS_STRING:
218+
return ZSTR_KNOWN(ZEND_STR_STRING);
219+
case IS_ARRAY:
220+
return ZSTR_KNOWN(ZEND_STR_ARRAY);
221+
case IS_OBJECT:
222+
return ZSTR_KNOWN(ZEND_STR_OBJECT);
223+
case IS_RESOURCE:
224+
if (zend_rsrc_list_get_rsrc_type(Z_RES_P(arg))) {
225+
return ZSTR_KNOWN(ZEND_STR_RESOURCE);
226+
} else {
227+
return ZSTR_KNOWN(ZEND_STR_CLOSED_RESOURCE);
228+
}
229+
default:
230+
return NULL;
231+
}
232+
}
233+
/* }}} */
234+
205235
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(zend_bool throw_, int num_args, int min_num_args, int max_num_args) /* {{{ */
206236
{
207237
zend_function *active_function = EG(current_execute_data)->func;

Zend/zend_API.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...);
277277
ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_spec, ...);
278278
ZEND_API int zend_parse_parameters_throw(int num_args, const char *type_spec, ...);
279279
ZEND_API char *zend_zval_type_name(const zval *arg);
280+
ZEND_API zend_string *zend_zval_get_type(const zval *arg);
280281

281282
ZEND_API int zend_parse_method_parameters(int num_args, zval *this_ptr, const char *type_spec, ...);
282283
ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this_ptr, const char *type_spec, ...);

Zend/zend_compile.c

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3644,23 +3644,38 @@ static int zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{
36443644
zend_op *opline;
36453645

36463646
if (args->children == 3) {
3647-
if (args->child[2]->kind != ZEND_AST_ZVAL) {
3647+
if (args->child[2]->kind == ZEND_AST_ZVAL) {
3648+
strict = zend_is_true(zend_ast_get_zval(args->child[2]));
3649+
} else if (args->child[2]->kind == ZEND_AST_CONST) {
3650+
zval value;
3651+
zend_ast *name_ast = args->child[2]->child[0];
3652+
zend_bool is_fully_qualified;
3653+
zend_string *resolved_name = zend_resolve_const_name(
3654+
zend_ast_get_str(name_ast), name_ast->attr, &is_fully_qualified);
3655+
3656+
if (!zend_try_ct_eval_const(&value, resolved_name, is_fully_qualified)) {
3657+
zend_string_release(resolved_name);
3658+
return FAILURE;
3659+
}
3660+
3661+
zend_string_release(resolved_name);
3662+
strict = zend_is_true(&value);
3663+
zval_ptr_dtor(&value);
3664+
} else {
36483665
return FAILURE;
36493666
}
3650-
strict = zend_is_true(zend_ast_get_zval(args->child[2]));
3667+
} else if (args->children != 2) {
3668+
return FAILURE;
36513669
}
36523670

3653-
if (args->children < 2
3654-
|| args->children > 3
3655-
|| args->child[1]->kind != ZEND_AST_ARRAY
3671+
if (args->child[1]->kind != ZEND_AST_ARRAY
36563672
|| !zend_try_ct_eval_array(&array.u.constant, args->child[1])) {
36573673
return FAILURE;
36583674
}
36593675

36603676
if (zend_hash_num_elements(Z_ARRVAL(array.u.constant)) > 0) {
36613677
zend_bool ok = 1;
36623678
zval *val, tmp;
3663-
zend_ulong idx;
36643679
HashTable *src = Z_ARRVAL(array.u.constant);
36653680
HashTable *dst = emalloc(sizeof(HashTable));
36663681

@@ -3681,7 +3696,8 @@ static int zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{
36813696
} ZEND_HASH_FOREACH_END();
36823697
} else {
36833698
ZEND_HASH_FOREACH_VAL(src, val) {
3684-
if (Z_TYPE_P(val) != IS_STRING || ZEND_HANDLE_NUMERIC(Z_STR_P(val), idx)) {
3699+
if (Z_TYPE_P(val) != IS_STRING
3700+
|| is_numeric_string(Z_STRVAL_P(val), Z_STRLEN_P(val), NULL, NULL, 0)) {
36853701
zend_array_destroy(dst);
36863702
ok = 0;
36873703
break;
@@ -3707,6 +3723,63 @@ static int zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{
37073723
}
37083724
/* }}} */
37093725

3726+
int zend_compile_func_count(znode *result, zend_ast_list *args) /* {{{ */
3727+
{
3728+
znode arg_node;
3729+
3730+
if (args->children != 1 || args->child[0]->kind == ZEND_AST_UNPACK) {
3731+
return FAILURE;
3732+
}
3733+
3734+
zend_compile_expr(&arg_node, args->child[0]);
3735+
zend_emit_op_tmp(result, ZEND_COUNT, &arg_node, NULL);
3736+
return SUCCESS;
3737+
}
3738+
/* }}} */
3739+
3740+
int zend_compile_func_get_class(znode *result, zend_ast_list *args) /* {{{ */
3741+
{
3742+
if (args->children == 0) {
3743+
zend_emit_op_tmp(result, ZEND_GET_CLASS, NULL, NULL);
3744+
} else {
3745+
znode arg_node;
3746+
3747+
if (args->children != 1 || args->child[0]->kind == ZEND_AST_UNPACK) {
3748+
return FAILURE;
3749+
}
3750+
3751+
zend_compile_expr(&arg_node, args->child[0]);
3752+
zend_emit_op_tmp(result, ZEND_GET_CLASS, &arg_node, NULL);
3753+
}
3754+
return SUCCESS;
3755+
}
3756+
/* }}} */
3757+
3758+
int zend_compile_func_get_called_class(znode *result, zend_ast_list *args) /* {{{ */
3759+
{
3760+
if (args->children != 0) {
3761+
return FAILURE;
3762+
}
3763+
3764+
zend_emit_op_tmp(result, ZEND_GET_CALLED_CLASS, NULL, NULL);
3765+
return SUCCESS;
3766+
}
3767+
/* }}} */
3768+
3769+
int zend_compile_func_gettype(znode *result, zend_ast_list *args) /* {{{ */
3770+
{
3771+
znode arg_node;
3772+
3773+
if (args->children != 1 || args->child[0]->kind == ZEND_AST_UNPACK) {
3774+
return FAILURE;
3775+
}
3776+
3777+
zend_compile_expr(&arg_node, args->child[0]);
3778+
zend_emit_op_tmp(result, ZEND_GET_TYPE, &arg_node, NULL);
3779+
return SUCCESS;
3780+
}
3781+
/* }}} */
3782+
37103783
int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc, uint32_t type) /* {{{ */
37113784
{
37123785
if (fbc->internal_function.handler == ZEND_FN(display_disabled_function)) {
@@ -3767,6 +3840,14 @@ int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_l
37673840
return zend_compile_func_cuf(result, args, lcname);
37683841
} else if (zend_string_equals_literal(lcname, "in_array")) {
37693842
return zend_compile_func_in_array(result, args);
3843+
} else if (zend_string_equals_literal(lcname, "count")) {
3844+
return zend_compile_func_count(result, args);
3845+
} else if (zend_string_equals_literal(lcname, "get_class")) {
3846+
return zend_compile_func_get_class(result, args);
3847+
} else if (zend_string_equals_literal(lcname, "get_called_class")) {
3848+
return zend_compile_func_get_called_class(result, args);
3849+
} else if (zend_string_equals_literal(lcname, "gettype")) {
3850+
return zend_compile_func_gettype(result, args);
37703851
} else {
37713852
return FAILURE;
37723853
}

Zend/zend_interfaces.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ ZEND_API zend_class_entry *zend_ce_aggregate;
2828
ZEND_API zend_class_entry *zend_ce_iterator;
2929
ZEND_API zend_class_entry *zend_ce_arrayaccess;
3030
ZEND_API zend_class_entry *zend_ce_serializable;
31+
ZEND_API zend_class_entry *zend_ce_countable;
3132

3233
/* {{{ zend_call_method
3334
Only returns the returned zval if retval_ptr != NULL */
@@ -470,6 +471,13 @@ static int zend_implement_serializable(zend_class_entry *interface, zend_class_e
470471
}
471472
/* }}}*/
472473

474+
/* {{{ zend_implement_countable */
475+
static int zend_implement_countable(zend_class_entry *interface, zend_class_entry *class_type)
476+
{
477+
return SUCCESS;
478+
}
479+
/* }}}*/
480+
473481
/* {{{ function tables */
474482
const zend_function_entry zend_funcs_aggregate[] = {
475483
ZEND_ABSTRACT_ME(iterator, getIterator, NULL)
@@ -517,6 +525,14 @@ const zend_function_entry zend_funcs_serializable[] = {
517525
ZEND_FENTRY(unserialize, NULL, arginfo_serializable_serialize, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR)
518526
ZEND_FE_END
519527
};
528+
529+
ZEND_BEGIN_ARG_INFO(arginfo_countable_count, 0)
530+
ZEND_END_ARG_INFO()
531+
532+
const zend_function_entry zend_funcs_countable[] = {
533+
ZEND_ABSTRACT_ME(Countable, count, arginfo_countable_count)
534+
ZEND_FE_END
535+
};
520536
/* }}} */
521537

522538
/* {{{ zend_register_interfaces */
@@ -533,6 +549,8 @@ ZEND_API void zend_register_interfaces(void)
533549
REGISTER_MAGIC_INTERFACE(arrayaccess, ArrayAccess);
534550

535551
REGISTER_MAGIC_INTERFACE(serializable, Serializable);
552+
553+
REGISTER_MAGIC_INTERFACE(countable, Countable);
536554
}
537555
/* }}} */
538556

Zend/zend_interfaces.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extern ZEND_API zend_class_entry *zend_ce_aggregate;
3131
extern ZEND_API zend_class_entry *zend_ce_iterator;
3232
extern ZEND_API zend_class_entry *zend_ce_arrayaccess;
3333
extern ZEND_API zend_class_entry *zend_ce_serializable;
34+
extern ZEND_API zend_class_entry *zend_ce_countable;
3435

3536
typedef struct _zend_user_iterator {
3637
zend_object_iterator it;

Zend/zend_string.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,13 @@ EMPTY_SWITCH_DEFAULT_CASE()
416416
_(ZEND_STR_PATH, "path") \
417417
_(ZEND_STR_QUERY, "query") \
418418
_(ZEND_STR_FRAGMENT, "fragment") \
419+
_(ZEND_STR_NULL, "NULL") \
420+
_(ZEND_STR_BOOLEAN, "boolean") \
421+
_(ZEND_STR_INTEGER, "integer") \
422+
_(ZEND_STR_DOUBLE, "double") \
423+
_(ZEND_STR_ARRAY, "array") \
424+
_(ZEND_STR_RESOURCE, "resource") \
425+
_(ZEND_STR_CLOSED_RESOURCE, "resource (closed)") \
419426

420427

421428
typedef enum _zend_known_string_id {

0 commit comments

Comments
 (0)