Skip to content

Commit 582882a

Browse files
committed
Constant evaluation of few more constant functions
1 parent c41d253 commit 582882a

File tree

1 file changed

+215
-116
lines changed

1 file changed

+215
-116
lines changed

ext/opcache/Optimizer/sccp.c

Lines changed: 215 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -501,143 +501,242 @@ static inline int ct_eval_func_call(
501501
zend_function *func;
502502
int overflow;
503503

504-
if (zend_string_equals_literal(name, "chr")) {
505-
zend_long c;
506-
if (num_args != 1 || Z_TYPE_P(args[0]) != IS_LONG) {
507-
return FAILURE;
508-
}
509-
510-
c = Z_LVAL_P(args[0]) & 0xff;
511-
ZVAL_INTERNED_STR(result, ZSTR_CHAR(c));
512-
return SUCCESS;
513-
} else if (zend_string_equals_literal(name, "count")) {
514-
if (num_args != 1 || Z_TYPE_P(args[0]) != IS_ARRAY) {
504+
if (num_args == 0) {
505+
if (zend_string_equals_literal(name, "get_magic_quotes_gpc")
506+
|| zend_string_equals_literal(name, "get_magic_quotes_gpc_runtime")
507+
|| zend_string_equals_literal(name, "php_sapi_name")
508+
|| zend_string_equals_literal(name, "imagetypes")
509+
|| zend_string_equals_literal(name, "phpversion")) {
510+
/* pass */
511+
} else {
515512
return FAILURE;
516513
}
514+
} else if (num_args == 1) {
515+
if (zend_string_equals_literal(name, "chr")) {
516+
zend_long c;
517+
if (Z_TYPE_P(args[0]) != IS_LONG) {
518+
return FAILURE;
519+
}
517520

518-
ZVAL_LONG(result, zend_hash_num_elements(Z_ARRVAL_P(args[0])));
519-
return SUCCESS;
520-
} else if (zend_string_equals_literal(name, "ini_get")) {
521-
zend_ini_entry *ini_entry;
521+
c = Z_LVAL_P(args[0]) & 0xff;
522+
ZVAL_INTERNED_STR(result, ZSTR_CHAR(c));
523+
return SUCCESS;
524+
} else if (zend_string_equals_literal(name, "count")) {
525+
if (Z_TYPE_P(args[0]) != IS_ARRAY) {
526+
return FAILURE;
527+
}
522528

523-
if (num_args != 1 || Z_TYPE_P(args[0]) != IS_STRING) {
524-
return FAILURE;
525-
}
529+
ZVAL_LONG(result, zend_hash_num_elements(Z_ARRVAL_P(args[0])));
530+
return SUCCESS;
531+
} else if (zend_string_equals_literal(name, "ini_get")) {
532+
zend_ini_entry *ini_entry;
526533

527-
ini_entry = zend_hash_find_ptr(EG(ini_directives), Z_STR_P(args[0]));
528-
if (!ini_entry) {
529-
ZVAL_FALSE(result);
530-
} else if (ini_entry->modifiable != ZEND_INI_SYSTEM) {
531-
return FAILURE;
532-
} else if (ini_entry->value) {
533-
ZVAL_STR_COPY(result, ini_entry->value);
534-
} else {
535-
ZVAL_EMPTY_STRING(result);
536-
}
537-
return SUCCESS;
538-
} else if (zend_string_equals_literal(name, "in_array")) {
539-
if ((num_args != 2
540-
&& (num_args != 3
541-
|| (Z_TYPE_P(args[2]) != IS_FALSE
542-
&& Z_TYPE_P(args[2]) != IS_TRUE)))
543-
|| Z_TYPE_P(args[1]) != IS_ARRAY) {
544-
return FAILURE;
545-
}
546-
/* pass */
547-
} else if (zend_string_equals_literal(name, "strpos")) {
548-
if (num_args != 2
549-
|| Z_TYPE_P(args[0]) != IS_STRING
550-
|| Z_TYPE_P(args[1]) != IS_STRING
551-
|| !Z_STRLEN_P(args[1])) {
552-
return FAILURE;
553-
}
554-
/* pass */
555-
} else if (zend_string_equals_literal(name, "array_key_exists")) {
556-
if (num_args != 2 || Z_TYPE_P(args[1]) != IS_ARRAY ||
557-
(Z_TYPE_P(args[0]) != IS_LONG && Z_TYPE_P(args[0]) != IS_STRING
558-
&& Z_TYPE_P(args[0]) != IS_NULL)) {
559-
return FAILURE;
560-
}
561-
/* pass */
562-
} else if (zend_string_equals_literal(name, "trim")
563-
|| zend_string_equals_literal(name, "rtrim")
564-
|| zend_string_equals_literal(name, "ltrim")) {
565-
if ((num_args < 1 || num_args > 2) || Z_TYPE_P(args[0]) != IS_STRING
566-
|| (num_args == 2 && Z_TYPE_P(args[1]) != IS_STRING)) {
567-
return FAILURE;
568-
}
569-
/* pass */
570-
} else if (zend_string_equals_literal(name, "array_keys")
571-
|| zend_string_equals_literal(name, "array_values")) {
572-
if (num_args != 1 || Z_TYPE_P(args[0]) != IS_ARRAY) {
573-
return FAILURE;
574-
}
575-
/* pass */
576-
} else if (zend_string_equals_literal(name, "array_flip")) {
577-
zval *entry;
534+
if (Z_TYPE_P(args[0]) != IS_STRING) {
535+
return FAILURE;
536+
}
578537

579-
if (num_args != 1 || Z_TYPE_P(args[0]) != IS_ARRAY) {
580-
return FAILURE;
581-
}
582-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args[0]), entry) {
583-
if (Z_TYPE_P(entry) != IS_LONG && Z_TYPE_P(entry) != IS_STRING) {
538+
ini_entry = zend_hash_find_ptr(EG(ini_directives), Z_STR_P(args[0]));
539+
if (!ini_entry) {
540+
ZVAL_FALSE(result);
541+
} else if (ini_entry->modifiable != ZEND_INI_SYSTEM) {
584542
return FAILURE;
543+
} else if (ini_entry->value) {
544+
ZVAL_STR_COPY(result, ini_entry->value);
545+
} else {
546+
ZVAL_EMPTY_STRING(result);
585547
}
586-
} ZEND_HASH_FOREACH_END();
587-
/* pass */
588-
} else if (zend_string_equals_literal(name, "str_repeat")) {
589-
if (num_args != 2
590-
|| Z_TYPE_P(args[0]) != IS_STRING
591-
|| Z_TYPE_P(args[1]) != IS_LONG
592-
|| zend_safe_address(Z_STRLEN_P(args[0]), Z_LVAL_P(args[1]), 0, &overflow) > 64 * 1024
593-
|| overflow) {
594-
return FAILURE;
595-
}
596-
/* pass */
597-
} else if ((zend_string_equals_literal(name, "array_merge")
598-
|| zend_string_equals_literal(name, "array_replace")
599-
|| zend_string_equals_literal(name, "array_merge_recursive")
600-
|| zend_string_equals_literal(name, "array_merge_recursive")
601-
|| zend_string_equals_literal(name, "array_diff")
602-
|| zend_string_equals_literal(name, "array_diff_assoc")
603-
|| zend_string_equals_literal(name, "array_diff_key"))
604-
&& num_args > 0) {
605-
for (i = 0; i < num_args; i++) {
606-
if (Z_TYPE_P(args[i]) != IS_ARRAY) {
548+
return SUCCESS;
549+
} else if (zend_string_equals_literal(name, "trim")
550+
|| zend_string_equals_literal(name, "rtrim")
551+
|| zend_string_equals_literal(name, "ltrim")
552+
|| zend_string_equals_literal(name, "str_split")
553+
|| zend_string_equals_literal(name, "preg_quote")
554+
|| zend_string_equals_literal(name, "base64_encode")
555+
|| zend_string_equals_literal(name, "base64_decode")
556+
|| zend_string_equals_literal(name, "urlencode")
557+
|| zend_string_equals_literal(name, "urldecode")
558+
|| zend_string_equals_literal(name, "rawurlencode")
559+
|| zend_string_equals_literal(name, "rawurldecode")
560+
|| zend_string_equals_literal(name, "php_uname")) {
561+
if (Z_TYPE_P(args[0]) != IS_STRING) {
607562
return FAILURE;
608563
}
609-
}
610-
/* pass */
611-
} else if (zend_string_equals_literal(name, "implode")) {
612-
zval *entry;
564+
/* pass */
565+
} else if (zend_string_equals_literal(name, "array_keys")
566+
|| zend_string_equals_literal(name, "array_values")) {
567+
if (Z_TYPE_P(args[0]) != IS_ARRAY) {
568+
return FAILURE;
569+
}
570+
/* pass */
571+
} else if (zend_string_equals_literal(name, "array_flip")) {
572+
zval *entry;
613573

614-
if (!(num_args == 1 && Z_TYPE_P(args[0]) == IS_ARRAY)
615-
&& !(num_args == 2 && Z_TYPE_P(args[0]) == IS_STRING && Z_TYPE_P(args[1]) == IS_ARRAY)
616-
&& !(num_args == 2 && Z_TYPE_P(args[0]) == IS_ARRAY && Z_TYPE_P(args[1]) == IS_STRING)) {
617-
return FAILURE;
618-
}
574+
if (Z_TYPE_P(args[0]) != IS_ARRAY) {
575+
return FAILURE;
576+
}
577+
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args[0]), entry) {
578+
if (Z_TYPE_P(entry) != IS_LONG && Z_TYPE_P(entry) != IS_STRING) {
579+
return FAILURE;
580+
}
581+
} ZEND_HASH_FOREACH_END();
582+
/* pass */
583+
} else if (zend_string_equals_literal(name, "implode")) {
584+
zval *entry;
585+
586+
if (Z_TYPE_P(args[0]) != IS_ARRAY) {
587+
return FAILURE;
588+
}
619589

620-
if (Z_TYPE_P(args[0]) == IS_ARRAY) {
621590
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args[0]), entry) {
622591
if (Z_TYPE_P(entry) > IS_STRING) {
623592
return FAILURE;
624593
}
625594
} ZEND_HASH_FOREACH_END();
595+
/* pass */
596+
} else if (zend_string_equals_literal(name, "serialize")) {
597+
/* pass */
626598
} else {
627-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args[1]), entry) {
628-
if (Z_TYPE_P(entry) > IS_STRING) {
599+
return FAILURE;
600+
}
601+
} else if (num_args == 2) {
602+
if (zend_string_equals_literal(name, "in_array")) {
603+
if (Z_TYPE_P(args[1]) != IS_ARRAY) {
604+
return FAILURE;
605+
}
606+
/* pass */
607+
} else if (zend_string_equals_literal(name, "strpos")) {
608+
if (Z_TYPE_P(args[0]) != IS_STRING
609+
|| Z_TYPE_P(args[1]) != IS_STRING
610+
|| !Z_STRLEN_P(args[1])) {
611+
return FAILURE;
612+
}
613+
/* pass */
614+
} else if (zend_string_equals_literal(name, "str_split")) {
615+
if (Z_TYPE_P(args[0]) != IS_STRING
616+
|| Z_TYPE_P(args[1]) != IS_LONG
617+
|| !Z_LVAL_P(args[1]) <= 0) {
618+
return FAILURE;
619+
}
620+
/* pass */
621+
} else if (zend_string_equals_literal(name, "array_key_exists")) {
622+
if (Z_TYPE_P(args[1]) != IS_ARRAY
623+
|| (Z_TYPE_P(args[0]) != IS_LONG
624+
&& Z_TYPE_P(args[0]) != IS_STRING
625+
&& Z_TYPE_P(args[0]) != IS_NULL)) {
626+
return FAILURE;
627+
}
628+
/* pass */
629+
} else if (zend_string_equals_literal(name, "trim")
630+
|| zend_string_equals_literal(name, "rtrim")
631+
|| zend_string_equals_literal(name, "ltrim")
632+
|| zend_string_equals_literal(name, "preg_quote")) {
633+
if (Z_TYPE_P(args[0]) != IS_STRING
634+
|| Z_TYPE_P(args[1]) != IS_STRING) {
635+
return FAILURE;
636+
}
637+
/* pass */
638+
} else if (zend_string_equals_literal(name, "str_repeat")) {
639+
if (Z_TYPE_P(args[0]) != IS_STRING
640+
|| Z_TYPE_P(args[1]) != IS_LONG
641+
|| zend_safe_address(Z_STRLEN_P(args[0]), Z_LVAL_P(args[1]), 0, &overflow) > 64 * 1024
642+
|| overflow) {
643+
return FAILURE;
644+
}
645+
/* pass */
646+
} else if (zend_string_equals_literal(name, "array_merge")
647+
|| zend_string_equals_literal(name, "array_replace")
648+
|| zend_string_equals_literal(name, "array_merge_recursive")
649+
|| zend_string_equals_literal(name, "array_merge_recursive")
650+
|| zend_string_equals_literal(name, "array_diff")
651+
|| zend_string_equals_literal(name, "array_diff_assoc")
652+
|| zend_string_equals_literal(name, "array_diff_key")) {
653+
for (i = 0; i < num_args; i++) {
654+
if (Z_TYPE_P(args[i]) != IS_ARRAY) {
629655
return FAILURE;
630656
}
631-
} ZEND_HASH_FOREACH_END();
657+
}
658+
/* pass */
659+
} else if (zend_string_equals_literal(name, "implode")) {
660+
zval *entry;
661+
662+
if ((Z_TYPE_P(args[0]) != IS_STRING || Z_TYPE_P(args[1]) != IS_ARRAY)
663+
&& (Z_TYPE_P(args[0]) != IS_ARRAY || Z_TYPE_P(args[1]) != IS_STRING)) {
664+
return FAILURE;
665+
}
666+
667+
if (Z_TYPE_P(args[0]) == IS_ARRAY) {
668+
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args[0]), entry) {
669+
if (Z_TYPE_P(entry) > IS_STRING) {
670+
return FAILURE;
671+
}
672+
} ZEND_HASH_FOREACH_END();
673+
} else {
674+
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args[1]), entry) {
675+
if (Z_TYPE_P(entry) > IS_STRING) {
676+
return FAILURE;
677+
}
678+
} ZEND_HASH_FOREACH_END();
679+
}
680+
/* pass */
681+
} else if (zend_string_equals_literal(name, "version_compare")) {
682+
if (Z_TYPE_P(args[0]) != IS_STRING
683+
|| Z_TYPE_P(args[1]) != IS_STRING) {
684+
return FAILURE;
685+
}
686+
/* pass */
687+
} else if (zend_string_equals_literal(name, "substr")) {
688+
if (Z_TYPE_P(args[0]) != IS_STRING
689+
|| Z_TYPE_P(args[1]) != IS_LONG) {
690+
return FAILURE;
691+
}
692+
/* pass */
693+
} else if (zend_string_equals_literal(name, "pow")) {
694+
if ((Z_TYPE_P(args[0]) != IS_LONG && Z_TYPE_P(args[0]) != IS_DOUBLE)
695+
|| (Z_TYPE_P(args[1]) != IS_LONG && Z_TYPE_P(args[1]) != IS_DOUBLE)) {
696+
return FAILURE;
697+
}
698+
/* pass */
699+
} else {
700+
return FAILURE;
632701
}
633-
/* pass */
634-
} else if (zend_string_equals_literal(name, "version_comapre")) {
635-
if ((num_args != 2 && (num_args != 3 || Z_TYPE_P(args[2]) != IS_STRING))
636-
|| Z_TYPE_P(args[0]) != IS_STRING
637-
|| Z_TYPE_P(args[1]) != IS_STRING) {
702+
} else if (num_args == 3) {
703+
if (zend_string_equals_literal(name, "in_array")) {
704+
if (Z_TYPE_P(args[1]) != IS_ARRAY
705+
|| (Z_TYPE_P(args[2]) != IS_FALSE
706+
&& Z_TYPE_P(args[2]) != IS_TRUE)) {
707+
return FAILURE;
708+
}
709+
/* pass */
710+
} else if (zend_string_equals_literal(name, "array_merge")
711+
|| zend_string_equals_literal(name, "array_replace")
712+
|| zend_string_equals_literal(name, "array_merge_recursive")
713+
|| zend_string_equals_literal(name, "array_merge_recursive")
714+
|| zend_string_equals_literal(name, "array_diff")
715+
|| zend_string_equals_literal(name, "array_diff_assoc")
716+
|| zend_string_equals_literal(name, "array_diff_key")) {
717+
for (i = 0; i < num_args; i++) {
718+
if (Z_TYPE_P(args[i]) != IS_ARRAY) {
719+
return FAILURE;
720+
}
721+
}
722+
/* pass */
723+
} else if (zend_string_equals_literal(name, "version_compare")) {
724+
if (Z_TYPE_P(args[0]) != IS_STRING
725+
|| Z_TYPE_P(args[1]) != IS_STRING
726+
|| Z_TYPE_P(args[2]) != IS_STRING) {
727+
return FAILURE;
728+
}
729+
/* pass */
730+
} else if (zend_string_equals_literal(name, "substr")) {
731+
if (Z_TYPE_P(args[0]) != IS_STRING
732+
|| Z_TYPE_P(args[1]) != IS_LONG
733+
|| Z_TYPE_P(args[2]) != IS_LONG) {
734+
return FAILURE;
735+
}
736+
/* pass */
737+
} else {
638738
return FAILURE;
639739
}
640-
/* pass */
641740
} else {
642741
return FAILURE;
643742
}
@@ -1059,8 +1158,8 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
10591158
break;
10601159
}
10611160

1062-
/* We're only interested in functions with one, two or three arguments right now */
1063-
if (call->num_args == 0 || call->num_args > 3) {
1161+
/* We're only interested in functions with up to three arguments right now */
1162+
if (call->num_args > 3) {
10641163
SET_RESULT_BOT(result);
10651164
break;
10661165
}

0 commit comments

Comments
 (0)