Skip to content

Commit 6800460

Browse files
committed
Support for few more internal functions evaluation
1 parent 74a2946 commit 6800460

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

ext/opcache/Optimizer/sccp.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,59 @@ static inline int ct_eval_func_call(
531531
}
532532
ZVAL_STR(result, str);
533533
return SUCCESS;
534+
} else {
535+
uint32_t i;
536+
zend_execute_data *execute_data;
537+
zend_function *func;
538+
int overflow;
539+
540+
if ((zend_string_equals_literal(name, "array_keys")
541+
|| zend_string_equals_literal(name, "array_values"))
542+
&& num_args == 1
543+
&& Z_TYPE_P(args[0]) == IS_ARRAY) {
544+
/* pass */
545+
} else if (zend_string_equals_literal(name, "str_repeat")
546+
&& num_args == 2
547+
&& Z_TYPE_P(args[0]) == IS_STRING
548+
&& Z_TYPE_P(args[1]) == IS_LONG
549+
&& zend_safe_address(Z_STRLEN_P(args[0]), Z_LVAL_P(args[1]), 0, &overflow) < 64 * 1024 * 1024
550+
&& !overflow) {
551+
/* pass */
552+
} else if ((zend_string_equals_literal(name, "array_merge")
553+
|| zend_string_equals_literal(name, "array_replace")
554+
|| zend_string_equals_literal(name, "array_merge_recursive")
555+
|| zend_string_equals_literal(name, "array_merge_recursive"))
556+
&& num_args > 0) {
557+
for (i = 0; i < num_args; i++) {
558+
if (Z_TYPE_P(args[i]) != IS_ARRAY) {
559+
return FAILURE;
560+
}
561+
}
562+
} else {
563+
#if 0
564+
fprintf(stderr, "constant ICALL to %s()\n", ZSTR_VAL(name));
565+
#endif
566+
return FAILURE;
567+
}
568+
569+
func = zend_hash_find_ptr(CG(function_table), name);
570+
if (!func || func->type != ZEND_INTERNAL_FUNCTION) {
571+
return FAILURE;
572+
}
573+
574+
execute_data = safe_emalloc(num_args, sizeof(zval), ZEND_CALL_FRAME_SLOT * sizeof(zval));
575+
memset(execute_data, 0, sizeof(zend_execute_data));
576+
EX(func) = func;
577+
EX_NUM_ARGS() = num_args;
578+
for (i = 0; i < num_args; i++) {
579+
ZVAL_COPY(EX_VAR_NUM(i), args[i]);
580+
}
581+
func->internal_function.handler(execute_data, result);
582+
for (i = 0; i < num_args; i++) {
583+
zval_ptr_dtor_nogc(EX_VAR_NUM(i));
584+
}
585+
efree(execute_data);
586+
return SUCCESS;
534587
}
535588
return FAILURE;
536589
}

0 commit comments

Comments
 (0)