Skip to content

Commit f6600bd

Browse files
committed
also try smth for longs
1 parent 21faf21 commit f6600bd

File tree

5 files changed

+87
-42
lines changed

5 files changed

+87
-42
lines changed

Zend/zend_API.c

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -554,14 +554,17 @@ ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *
554554
return zend_parse_arg_bool_weak(arg, dest, arg_num);
555555
}
556556

557-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num) /* {{{ */
557+
ZEND_API zend_opt_long ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, uint32_t arg_num) /* {{{ */
558558
{
559+
zend_opt_long result;
560+
result.has_value = false;
561+
559562
if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
560563
if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
561-
return 0;
564+
return result;
562565
}
563566
if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
564-
return 0;
567+
return result;
565568
} else {
566569
zend_long lval = zend_dval_to_lval(Z_DVAL_P(arg));
567570
if (UNEXPECTED(!zend_is_long_compatible(Z_DVAL_P(arg), lval))) {
@@ -571,23 +574,24 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long
571574
zend_incompatible_double_to_long_error(Z_DVAL_P(arg));
572575
}
573576
if (UNEXPECTED(EG(exception))) {
574-
return 0;
577+
return result;
575578
}
576579
}
577-
*dest = lval;
580+
result.value = lval;
581+
result.has_value = true;
578582
}
579583
} else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
580584
double d;
581585
uint8_t type;
582586

583-
if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) {
587+
if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &result.value, &d)) != IS_LONG)) {
584588
if (EXPECTED(type != 0)) {
585589
zend_long lval;
586590
if (UNEXPECTED(zend_isnan(d))) {
587-
return 0;
591+
return result;
588592
}
589593
if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
590-
return 0;
594+
return result;
591595
}
592596

593597
lval = zend_dval_to_lval(d);
@@ -599,46 +603,54 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long
599603
zend_incompatible_string_to_long_error(Z_STR_P(arg));
600604
}
601605
if (UNEXPECTED(EG(exception))) {
602-
return 0;
606+
return result;
603607
}
604608
}
605-
*dest = lval;
609+
result.value = lval;
610+
result.has_value = true;
606611
} else {
607-
return 0;
612+
return result;
608613
}
614+
} else {
615+
result.has_value = true;
609616
}
610617
if (UNEXPECTED(EG(exception))) {
611-
return 0;
618+
result.has_value = false;
619+
return result;
612620
}
613621
} else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
614622
if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("int", arg_num)) {
615-
return 0;
623+
return result;
616624
}
617-
*dest = 0;
625+
result.value = 0;
626+
result.has_value = true;
618627
} else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
619-
*dest = 1;
620-
} else {
621-
return 0;
628+
result.value = 1;
629+
result.has_value = true;
622630
}
623-
return 1;
631+
return result;
624632
}
625633
/* }}} */
626634

627-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num) /* {{{ */
635+
ZEND_API zend_opt_long ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, uint32_t arg_num) /* {{{ */
628636
{
629637
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
630-
return 0;
638+
zend_opt_long result;
639+
result.has_value = false;
640+
return result;
631641
}
632-
return zend_parse_arg_long_weak(arg, dest, arg_num);
642+
return zend_parse_arg_long_weak(arg, arg_num);
633643
}
634644
/* }}} */
635645

636-
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num)
646+
ZEND_API zend_opt_long ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, uint32_t arg_num)
637647
{
638648
if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) {
639-
return 0;
649+
zend_opt_long result;
650+
result.has_value = false;
651+
return result;
640652
}
641-
return zend_parse_arg_long_weak(arg, dest, arg_num);
653+
return zend_parse_arg_long_weak(arg, arg_num);
642654
}
643655

644656
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */
@@ -793,7 +805,9 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_stri
793805
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
794806
return 0;
795807
}
796-
if (zend_parse_arg_long_weak(arg, dest_long, arg_num)) {
808+
zend_opt_long result = zend_parse_arg_long_weak(arg, arg_num);
809+
if (result.has_value) {
810+
*dest_long = result.value;
797811
*dest_str = NULL;
798812
return 1;
799813
} else {

Zend/zend_API.h

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2174,11 +2174,16 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string
21742174

21752175
/* Inlined implementations shared by new and old parameter parsing APIs */
21762176

2177+
typedef struct {
2178+
zend_long value;
2179+
bool has_value;
2180+
} zend_opt_long;
2181+
21772182
ZEND_API bool ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, uint32_t num, bool check_null);
21782183
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
21792184
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num);
2180-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num);
2181-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num);
2185+
ZEND_API zend_opt_long ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, uint32_t arg_num);
2186+
ZEND_API zend_opt_long ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, uint32_t arg_num);
21822187
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num);
21832188
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num);
21842189
ZEND_API zend_string * ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num);
@@ -2189,7 +2194,7 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_stri
21892194

21902195
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
21912196
ZEND_API zend_string * ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num);
2192-
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num);
2197+
ZEND_API zend_opt_long ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, uint32_t arg_num);
21932198

21942199
static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num, bool frameless)
21952200
{
@@ -2229,10 +2234,16 @@ static zend_always_inline bool zend_parse_arg_long_ex(zval *arg, zend_long *dest
22292234
*is_null = 1;
22302235
*dest = 0;
22312236
} else {
2237+
zend_opt_long result;
22322238
if (frameless) {
2233-
return zend_flf_parse_arg_long_slow(arg, dest, arg_num);
2239+
result = zend_flf_parse_arg_long_slow(arg, arg_num);
22342240
} else {
2235-
return zend_parse_arg_long_slow(arg, dest, arg_num);
2241+
result = zend_parse_arg_long_slow(arg, arg_num);
2242+
}
2243+
if (result.has_value) {
2244+
*dest = result.value;
2245+
} else {
2246+
return 0;
22362247
}
22372248
}
22382249
return 1;
@@ -2421,7 +2432,12 @@ static zend_always_inline bool zend_parse_arg_array_ht_or_long(
24212432
*is_null = 1;
24222433
} else {
24232434
*dest_ht = NULL;
2424-
return zend_parse_arg_long_slow(arg, dest_long, arg_num);
2435+
zend_opt_long result = zend_parse_arg_long_slow(arg, arg_num);
2436+
if (result.has_value) {
2437+
*dest_long = result.value;
2438+
} else {
2439+
return 0;
2440+
}
24252441
}
24262442

24272443
return 1;
@@ -2470,7 +2486,12 @@ static zend_always_inline bool zend_parse_arg_obj_or_long(
24702486
*is_null = 1;
24712487
} else {
24722488
*dest_obj = NULL;
2473-
return zend_parse_arg_long_slow(arg, dest_long, arg_num);
2489+
zend_opt_long result = zend_parse_arg_long_slow(arg, arg_num);
2490+
if (result.has_value) {
2491+
*dest_long = result.value;
2492+
} else {
2493+
return 0;
2494+
}
24742495
}
24752496

24762497
return 1;

Zend/zend_execute.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -743,12 +743,15 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
743743
ZVAL_DOUBLE(arg, dval);
744744
return 1;
745745
}
746-
} else if (zend_parse_arg_long_weak(arg, &lval, 0)) {
747-
zval_ptr_dtor(arg);
748-
ZVAL_LONG(arg, lval);
749-
return 1;
750-
} else if (UNEXPECTED(EG(exception))) {
751-
return 0;
746+
} else {
747+
zend_opt_long result = zend_parse_arg_long_weak(arg, 0);
748+
if (result.has_value) {
749+
zval_ptr_dtor(arg);
750+
ZVAL_LONG(arg, result.value);
751+
return 1;
752+
} else if (UNEXPECTED(EG(exception))) {
753+
return 0;
754+
}
752755
}
753756
}
754757
if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, 0)) {
@@ -783,13 +786,12 @@ static bool can_convert_to_string(const zval *zv) {
783786
/* Used to sanity-check internal arginfo types without performing any actual type conversions. */
784787
static bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_mask, const zval *arg)
785788
{
786-
zend_long lval;
787789
double dval;
788790
bool bval;
789791

790792
/* Pass (uint32_t)-1 as arg_num to indicate to ZPP not to emit any deprecation notice,
791793
* this is needed because the version with side effects also uses 0 (e.g. for typed properties) */
792-
if ((type_mask & MAY_BE_LONG) && zend_parse_arg_long_weak(arg, &lval, (uint32_t)-1)) {
794+
if ((type_mask & MAY_BE_LONG) && zend_parse_arg_long_weak(arg, (uint32_t)-1).has_value) {
793795
return 1;
794796
}
795797
if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, (uint32_t)-1)) {

Zend/zend_vm_def.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5501,18 +5501,22 @@ ZEND_VM_C_LABEL(send_array):
55015501
uint32_t skip = opline->extended_value;
55025502
uint32_t count = zend_hash_num_elements(ht);
55035503
zend_long len;
5504+
zend_opt_long result;
55045505
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
55055506
len = Z_LVAL_P(op2);
55065507
} else if (Z_TYPE_P(op2) == IS_NULL) {
55075508
len = count - skip;
55085509
} else if (EX_USES_STRICT_TYPES()
5509-
|| !zend_parse_arg_long_weak(op2, &len, /* arg_num */ 3)) {
5510+
|| !(result = zend_parse_arg_long_weak(op2, /* arg_num */ 3)).has_value) {
55105511
zend_type_error(
55115512
"array_slice(): Argument #3 ($length) must be of type ?int, %s given",
55125513
zend_zval_value_name(op2));
55135514
FREE_OP2();
55145515
FREE_OP1();
55155516
HANDLE_EXCEPTION();
5517+
} else {
5518+
ZEND_ASSERT(result.has_value);
5519+
len = result.value;
55165520
}
55175521

55185522
if (len < 0) {

Zend/zend_vm_execute.h

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)