Skip to content

Commit 3397f29

Browse files
committed
Merge remote-tracking branch 'origin/master' into opcache/file_cache_read_only
2 parents 86e5178 + bfca4c7 commit 3397f29

32 files changed

+348
-81
lines changed

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ PHP 8.5 UPGRADE NOTES
100100
9. Other Changes to Extensions
101101
========================================
102102

103+
- Readline:
104+
. The return types of readline_add_history(), readline_clear_history(), and
105+
readline_callback_handler_install() have been changed to true, rather
106+
than bool.
107+
103108
========================================
104109
10. New Global Constants
105110
========================================

Zend/tests/abstract_implicit.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Abstract methods not allowed in classes that are not abstract (GH-16067)
3+
--FILE--
4+
<?php
5+
6+
// Still allowed via trait
7+
trait TraitWithAbstract {
8+
abstract public function foo();
9+
}
10+
class TraitWorks {
11+
use TraitWithAbstract;
12+
}
13+
14+
class NotAbstract {
15+
abstract public function bar();
16+
}
17+
?>
18+
--EXPECTF--
19+
Fatal error: Class NotAbstract declares abstract method bar() and must therefore be declared abstract in %s on line %d

Zend/tests/anon/gh16067.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Compiler prevents explicit `abstract` methods on anonymous classes
3+
--FILE--
4+
<?php
5+
6+
$c = new class {
7+
abstract public function f();
8+
}
9+
?>
10+
--EXPECTF--
11+
Fatal error: Anonymous class method f() must not be abstract in %s on line 4

Zend/tests/enum/no-abstract.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Compiler prevents `abstract` methods on enums classes (GH-16067)
3+
--FILE--
4+
<?php
5+
6+
enum Example {
7+
abstract public function foo();
8+
}
9+
10+
?>
11+
--EXPECTF--
12+
Fatal error: Enum method Example::foo() must not be abstract in %s on line 4

Zend/tests/errmsg/errmsg_018.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ class test {
1010
echo "Done\n";
1111
?>
1212
--EXPECTF--
13-
Fatal error: Class test contains 1 abstract method and must therefore be declared abstract or implement the remaining method (test::foo) in %s on line %d
13+
Fatal error: Class test declares abstract method foo() and must therefore be declared abstract in %s on line %d

Zend/zend_compile.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3709,6 +3709,7 @@ static uint32_t zend_get_arg_num(zend_function *fn, zend_string *arg_name) {
37093709
}
37103710
}
37113711
} else {
3712+
ZEND_ASSERT(fn->common.num_args == 0 || fn->internal_function.arg_info);
37123713
for (uint32_t i = 0; i < fn->common.num_args; i++) {
37133714
zend_internal_arg_info *arg_info = &fn->internal_function.arg_info[i];
37143715
size_t len = strlen(arg_info->name);
@@ -8067,6 +8068,22 @@ static zend_string *zend_begin_method_decl(zend_op_array *op_array, zend_string
80678068
zend_error(E_COMPILE_WARNING, "Private methods cannot be final as they are never overridden by other classes");
80688069
}
80698070

8071+
if ((fn_flags & ZEND_ACC_ABSTRACT)
8072+
&& !(ce->ce_flags & (ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_TRAIT))) {
8073+
// Don't say that the class should be declared abstract if it is
8074+
// anonymous or an enum and can't be abstract
8075+
if (ce->ce_flags & ZEND_ACC_ANON_CLASS) {
8076+
zend_error_noreturn(E_COMPILE_ERROR, "Anonymous class method %s() must not be abstract",
8077+
ZSTR_VAL(name));
8078+
} else if (ce->ce_flags & (ZEND_ACC_ENUM|ZEND_ACC_INTERFACE)) {
8079+
zend_error_noreturn(E_COMPILE_ERROR, "%s method %s::%s() must not be abstract",
8080+
zend_get_object_type_case(ce, true), ZSTR_VAL(ce->name), ZSTR_VAL(name));
8081+
} else {
8082+
zend_error_noreturn(E_COMPILE_ERROR, "Class %s declares abstract method %s() and must therefore be declared abstract",
8083+
ZSTR_VAL(ce->name), ZSTR_VAL(name));
8084+
}
8085+
}
8086+
80708087
if (in_interface) {
80718088
if (!(fn_flags & ZEND_ACC_PUBLIC)) {
80728089
zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method "
@@ -8076,10 +8093,6 @@ static zend_string *zend_begin_method_decl(zend_op_array *op_array, zend_string
80768093
zend_error_noreturn(E_COMPILE_ERROR, "Interface method "
80778094
"%s::%s() must not be final", ZSTR_VAL(ce->name), ZSTR_VAL(name));
80788095
}
8079-
if (fn_flags & ZEND_ACC_ABSTRACT) {
8080-
zend_error_noreturn(E_COMPILE_ERROR, "Interface method "
8081-
"%s::%s() must not be abstract", ZSTR_VAL(ce->name), ZSTR_VAL(name));
8082-
}
80838096
op_array->fn_flags |= ZEND_ACC_ABSTRACT;
80848097
}
80858098

Zend/zend_execute.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5304,6 +5304,7 @@ static zend_always_inline uint32_t zend_get_arg_offset_by_name(
53045304
}
53055305
}
53065306
} else {
5307+
ZEND_ASSERT(num_args == 0 || fbc->internal_function.arg_info);
53075308
for (uint32_t i = 0; i < num_args; i++) {
53085309
zend_internal_arg_info *arg_info = &fbc->internal_function.arg_info[i];
53095310
size_t len = strlen(arg_info->name);

Zend/zend_max_execution_timer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121

2222
#include "zend_long.h"
2323

24+
BEGIN_EXTERN_C()
2425
/* Must be called after calls to fork() */
2526
ZEND_API void zend_max_execution_timer_init(void);
27+
END_EXTERN_C()
2628
void zend_max_execution_timer_settime(zend_long seconds);
2729
void zend_max_execution_timer_shutdown(void);
2830

Zend/zend_vm_def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3634,7 +3634,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV,
36343634
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
36353635
if (UNEXPECTED(fbc == NULL)) {
36363636
if (EXPECTED(!EG(exception))) {
3637-
zend_undefined_method(obj->ce, Z_STR_P(function_name));
3637+
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
36383638
}
36393639
FREE_OP2();
36403640
if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {

Zend/zend_vm_execute.h

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

ext/curl/tests/curl_version_features-array.phpt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,5 @@ Array
4949
[HTTPS_PROXY] => bool
5050
[MULTI_SSL] => bool
5151
[BROTLI] => bool
52-
%A
53-
)
52+
%A)
5453
Complete

ext/gd/libgd/gd_interpolation.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -919,21 +919,29 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
919919
return res;
920920
}
921921

922+
/* Convert a double to an unsigned char, rounding to the nearest
923+
* integer and clamping the result between 0 and max. The absolute
924+
* value of clr must be less than the maximum value of an unsigned
925+
* short. */
922926
static inline unsigned char
923-
uchar_clamp(double clr) {
927+
uchar_clamp(double clr, unsigned char max) {
924928
unsigned short result;
925-
assert(fabs(clr) <= SHRT_MAX);
929+
930+
//assert(fabs(clr) <= SHRT_MAX);
931+
926932
/* Casting a negative float to an unsigned short is undefined.
927933
* However, casting a float to a signed truncates toward zero and
928934
* casting a negative signed value to an unsigned of the same size
929935
* results in a bit-identical value (assuming twos-complement
930936
* arithmetic). This is what we want: all legal negative values
931937
* for clr will be greater than 255. */
938+
932939
/* Convert and clamp. */
933940
result = (unsigned short)(short)(clr + 0.5);
934-
if (result > 255) {
935-
result = (clr < 0) ? 0 : 255;
941+
if (result > max) {
942+
result = (clr < 0) ? 0 : max;
936943
}/* if */
944+
937945
return result;
938946
}/* uchar_clamp*/
939947

@@ -957,7 +965,9 @@ static inline void _gdScaleRow(gdImagePtr pSrc, unsigned int src_width, gdImage
957965
b += contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetBlue(p_src_row[i]));
958966
a += contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetAlpha(p_src_row[i]));
959967
}
960-
p_dst_row[x] = gdTrueColorAlpha(uchar_clamp(r), uchar_clamp(g), uchar_clamp(b), uchar_clamp(a));
968+
p_dst_row[x] = gdTrueColorAlpha(uchar_clamp(r, 0xFF), uchar_clamp(g, 0xFF),
969+
uchar_clamp(b, 0xFF),
970+
uchar_clamp(a, 0x7F)); /* alpha is 0..127 */
961971
}
962972
}
963973

@@ -1004,7 +1014,9 @@ static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImag
10041014
b += contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetBlue(pCurSrc));
10051015
a += contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetAlpha(pCurSrc));
10061016
}
1007-
pRes->tpixels[y][uCol] = gdTrueColorAlpha(uchar_clamp(r), uchar_clamp(g), uchar_clamp(b), uchar_clamp(a));
1017+
pRes->tpixels[y][uCol] = gdTrueColorAlpha(uchar_clamp(r, 0xFF), uchar_clamp(g, 0xFF),
1018+
uchar_clamp(b, 0xFF),
1019+
uchar_clamp(a, 0x7F)); /* alpha is 0..127 */
10081020
}
10091021
}
10101022

ext/gd/tests/gh16559.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-16559 (UBSan abort in ext/gd/libgd/gd_interpolation.c:1007)
3+
--EXTENSIONS--
4+
gd
5+
--FILE--
6+
<?php
7+
$input = imagecreatefrompng(__DIR__ . '/gh10614.png');
8+
for ($angle = 0; $angle <= 270; $angle += 90) {
9+
$output = imagerotate($input, $angle, 0);
10+
}
11+
var_dump(imagescale($output, -1, 64, IMG_BICUBIC));
12+
?>
13+
--EXPECT--
14+
object(GdImage)#2 (0) {
15+
}

ext/gmp/gmp.c

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,39 +1292,27 @@ ZEND_FUNCTION(gmp_pow)
12921292
RETURN_THROWS();
12931293
}
12941294

1295+
double powmax = log((double)ZEND_LONG_MAX);
1296+
12951297
if (Z_TYPE_P(base_arg) == IS_LONG && Z_LVAL_P(base_arg) >= 0) {
12961298
INIT_GMP_RETVAL(gmpnum_result);
1297-
if (exp >= INT_MAX) {
1298-
mpz_t base_num, exp_num, mod;
1299-
mpz_init(base_num);
1300-
mpz_init(exp_num);
1301-
mpz_init(mod);
1302-
mpz_set_si(base_num, Z_LVAL_P(base_arg));
1303-
mpz_set_si(exp_num, exp);
1304-
mpz_set_ui(mod, UINT_MAX);
1305-
mpz_powm(gmpnum_result, base_num, exp_num, mod);
1306-
mpz_clear(mod);
1307-
mpz_clear(exp_num);
1308-
mpz_clear(base_num);
1309-
} else {
1310-
mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp);
1299+
if ((log(Z_LVAL_P(base_arg)) * exp) > powmax) {
1300+
zend_value_error("base and exponent overflow");
1301+
RETURN_THROWS();
13111302
}
1303+
mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp);
13121304
} else {
13131305
mpz_ptr gmpnum_base;
1306+
zend_ulong gmpnum;
13141307
FETCH_GMP_ZVAL(gmpnum_base, base_arg, temp_base, 1);
13151308
INIT_GMP_RETVAL(gmpnum_result);
1316-
if (exp >= INT_MAX) {
1317-
mpz_t exp_num, mod;
1318-
mpz_init(exp_num);
1319-
mpz_init(mod);
1320-
mpz_set_si(exp_num, exp);
1321-
mpz_set_ui(mod, UINT_MAX);
1322-
mpz_powm(gmpnum_result, gmpnum_base, exp_num, mod);
1323-
mpz_clear(mod);
1324-
mpz_clear(exp_num);
1325-
} else {
1326-
mpz_pow_ui(gmpnum_result, gmpnum_base, exp);
1309+
gmpnum = mpz_get_ui(gmpnum_base);
1310+
if ((log(gmpnum) * exp) > powmax) {
1311+
FREE_GMP_TEMP(temp_base);
1312+
zend_value_error("base and exponent overflow");
1313+
RETURN_THROWS();
13271314
}
1315+
mpz_pow_ui(gmpnum_result, gmpnum_base, exp);
13281316
FREE_GMP_TEMP(temp_base);
13291317
}
13301318
}

ext/gmp/tests/gmp_pow.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
gmp_pow() basic tests
33
--EXTENSIONS--
44
gmp
5+
--SKIPIF--
6+
<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); ?>
57
--FILE--
68
<?php
79

0 commit comments

Comments
 (0)