Skip to content

Commit 2b7b7cc

Browse files
committed
2 parents 3648abe + 3f0df7a commit 2b7b7cc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+898
-1071
lines changed

NEWS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.0.0rc2
44

5+
- Curl:
6+
. Fixed bug #80121 (Null pointer deref if CurlHandle directly instantiated).
7+
(Nikita)
8+
9+
- SPL.
10+
. Fixed bug #65387 (Circular references in SPL iterators are not garbage
11+
collected). (Nikita)
512

613
01 Oct 2020, PHP 8.0.0rc1
714

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@ PHP 8.0 UPGRADE NOTES
341341

342342
- LDAP:
343343
. The deprecated function ldap_sort has been removed.
344+
. The deprecated function ldap_control_paged_result has been removed.
345+
. The deprecated function ldap_control_paged_result_response has been removed.
344346
. The interface of ldap_set_rebind_proc has changed; the $callback parameter
345347
does not accept empty string anymore; null value shall be used instead.
346348

@@ -606,6 +608,9 @@ PHP 8.0 UPGRADE NOTES
606608
. Calling crypt() without an explicit salt is no longer supported. If you
607609
would like to produce a strong hash with an auto-generated salt, use
608610
password_hash() instead.
611+
. substr(), mb_substr(), iconv_substr() and grapheme_substr() now consistently
612+
clamp out-of-bounds offsets to the string boundary. Previously, false was
613+
returned instead of the empty string in some cases.
609614

610615
- Sysvmsg:
611616
. msg_get_queue() will now return an SysvMessageQueue object rather than a

Zend/tests/div_by_zero_in_static.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Division by zero in static
3+
--FILE--
4+
<?php
5+
static $a = 1/0;
6+
?>
7+
--EXPECTF--
8+
Fatal error: Uncaught DivisionByZeroError: Division by zero in %s:%d
9+
Stack trace:
10+
#0 {main}
11+
thrown in %s on line %d
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Try to instantiate all classes without arguments
3+
--FILE--
4+
<?php
5+
6+
foreach (get_declared_classes() as $class) {
7+
try {
8+
new $class;
9+
} catch (Throwable) {}
10+
}
11+
12+
?>
13+
===DONE===
14+
--EXPECT--
15+
===DONE===

Zend/zend_operators.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,9 @@ ZEND_API zend_result ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *o
12531253
}
12541254
/* }}} */
12551255

1256-
static zend_result ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval *op2) /* {{{ */
1256+
/* Returns SUCCESS/FAILURE/TYPES_NOT_HANDLED */
1257+
#define TYPES_NOT_HANDLED 1
1258+
static int ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval *op2) /* {{{ */
12571259
{
12581260
zend_uchar type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2));
12591261

@@ -1290,23 +1292,25 @@ static zend_result ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval
12901292
ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
12911293
return SUCCESS;
12921294
} else {
1293-
return FAILURE;
1295+
return TYPES_NOT_HANDLED;
12941296
}
12951297
division_by_0:
12961298
if (result != op1) {
12971299
ZVAL_UNDEF(result);
12981300
}
12991301
zend_throw_error(zend_ce_division_by_zero_error, "Division by zero");
1300-
return SUCCESS;
1302+
return FAILURE;
13011303
}
13021304
/* }}} */
13031305

13041306
ZEND_API zend_result ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {{{ */
13051307
{
13061308
ZVAL_DEREF(op1);
13071309
ZVAL_DEREF(op2);
1308-
if (div_function_base(result, op1, op2) == SUCCESS) {
1309-
return SUCCESS;
1310+
1311+
int retval = div_function_base(result, op1, op2);
1312+
if (retval != TYPES_NOT_HANDLED) {
1313+
return retval;
13101314
}
13111315

13121316
ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV);
@@ -1325,12 +1329,9 @@ ZEND_API zend_result ZEND_FASTCALL div_function(zval *result, zval *op1, zval *o
13251329
zval_ptr_dtor(result);
13261330
}
13271331

1328-
if (div_function_base(result, &op1_copy, &op2_copy) == SUCCESS) {
1329-
return SUCCESS;
1330-
}
1331-
1332-
ZEND_ASSERT(0 && "Operation must succeed");
1333-
return FAILURE;
1332+
retval = div_function_base(result, &op1_copy, &op2_copy);
1333+
ZEND_ASSERT(retval != TYPES_NOT_HANDLED && "Types should be handled");
1334+
return retval;
13341335
}
13351336
/* }}} */
13361337

build/gen_stub.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ function processStubFile(string $stubFile, Context $context) {
3131
throw new Exception("File $stubFile does not exist");
3232
}
3333

34-
$arginfoFile = str_replace('.stub.php', '', $stubFile) . '_arginfo.h';
34+
$arginfoFile = str_replace('.stub.php', '', $stubFile)
35+
. ($context->legacy ? '_legacy' : '') . '_arginfo.h';
3536
$stubCode = file_get_contents($stubFile);
3637
$stubHash = computeStubHash($stubCode);
3738
$oldStubHash = extractStubHash($arginfoFile);
@@ -42,6 +43,12 @@ function processStubFile(string $stubFile, Context $context) {
4243

4344
initPhpParser();
4445
$fileInfo = parseStubFile($stubCode);
46+
if ($context->legacy) {
47+
foreach ($fileInfo->getAllFuncInfos() as $funcInfo) {
48+
$funcInfo->discardInfoForOldPhpVersions();
49+
}
50+
}
51+
4552
$arginfoCode = generateArgInfoCode($fileInfo, $stubHash);
4653
file_put_contents($arginfoFile, $arginfoCode);
4754

@@ -534,6 +541,14 @@ private function getFlagsAsString(): string
534541

535542
return $flags;
536543
}
544+
545+
public function discardInfoForOldPhpVersions(): void {
546+
$this->return->type = null;
547+
foreach ($this->args as $arg) {
548+
$arg->type = null;
549+
$arg->defaultValue = null;
550+
}
551+
}
537552
}
538553

539554
class ClassInfo {
@@ -1148,10 +1163,11 @@ function initPhpParser() {
11481163
}
11491164

11501165
$optind = null;
1151-
$options = getopt("f", ["force-regeneration", "parameter-stats"], $optind);
1166+
$options = getopt("f", ["force-regeneration", "parameter-stats", "legacy"], $optind);
11521167

11531168
$context = new Context;
11541169
$printParameterStats = isset($options["parameter-stats"]);
1170+
$context->legacy = isset($options["legacy"]);
11551171
$context->forceRegeneration =
11561172
isset($options["f"]) || isset($options["force-regeneration"]) || $printParameterStats;
11571173

ext/curl/interface.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3308,6 +3308,12 @@ static void curl_free_obj(zend_object *object)
33083308
fprintf(stderr, "DTOR CALLED, ch = %x\n", ch);
33093309
#endif
33103310

3311+
if (!ch->cp) {
3312+
/* Can happen if constructor throws. */
3313+
zend_object_std_dtor(&ch->std);
3314+
return;
3315+
}
3316+
33113317
_php_curl_verify_handlers(ch, 0);
33123318

33133319
/*
@@ -3321,12 +3327,10 @@ static void curl_free_obj(zend_object *object)
33213327
*
33223328
* Libcurl commit d021f2e8a00 fix this issue and should be part of 7.28.2
33233329
*/
3324-
if (ch->cp != NULL) {
3325-
curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_nothing);
3326-
curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write_nothing);
3330+
curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_nothing);
3331+
curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write_nothing);
33273332

3328-
curl_easy_cleanup(ch->cp);
3329-
}
3333+
curl_easy_cleanup(ch->cp);
33303334

33313335
/* cURL destructors should be invoked only by last curl handle */
33323336
if (--(*ch->clone) == 0) {

ext/curl/multi.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,12 @@ void curl_multi_free_obj(zend_object *object)
537537
php_curl *ch;
538538
zval *pz_ch;
539539

540+
if (!mh->multi) {
541+
/* Can happen if constructor throws. */
542+
zend_object_std_dtor(&mh->std);
543+
return;
544+
}
545+
540546
for (pz_ch = (zval *)zend_llist_get_first_ex(&mh->easyh, &pos); pz_ch;
541547
pz_ch = (zval *)zend_llist_get_next_ex(&mh->easyh, &pos)) {
542548
if (!(OBJ_FLAGS(Z_OBJ_P(pz_ch)) & IS_OBJ_FREE_CALLED)) {

ext/curl/tests/bug80121.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Bug #80121: Null pointer deref if CurlHandle directly instantiated
3+
--FILE--
4+
<?php
5+
6+
try {
7+
new CurlHandle;
8+
} catch (Error $e) {
9+
echo $e->getMessage(), "\n";
10+
}
11+
try {
12+
new CurlMultiHandle;
13+
} catch (Error $e) {
14+
echo $e->getMessage(), "\n";
15+
}
16+
try {
17+
new CurlShareHandle;
18+
} catch (Error $e) {
19+
echo $e->getMessage(), "\n";
20+
}
21+
22+
?>
23+
--EXPECT--
24+
Cannot directly construct CurlHandle, use curl_init() instead
25+
Cannot directly construct CurlMultiHandle, use curl_multi_init() instead
26+
Cannot directly construct CurlShareHandle, use curl_share_init() instead

ext/enchant/enchant.stub.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ function enchant_broker_free(EnchantBroker $broker): bool {}
1818
function enchant_broker_get_error(EnchantBroker $broker): string|false {}
1919

2020
/** @deprecated */
21-
function enchant_broker_set_dict_path(EnchantBroker $broker, int $name, string $value): bool {}
21+
function enchant_broker_set_dict_path(EnchantBroker $broker, int $type, string $path): bool {}
2222

2323
/** @deprecated */
24-
function enchant_broker_get_dict_path(EnchantBroker $broker, int $name): string|false {}
24+
function enchant_broker_get_dict_path(EnchantBroker $broker, int $type): string|false {}
2525

2626
function enchant_broker_list_dicts(EnchantBroker $broker): array {}
2727

@@ -30,7 +30,7 @@ function enchant_broker_request_dict(EnchantBroker $broker, string $tag): Enchan
3030
function enchant_broker_request_pwl_dict(EnchantBroker $broker, string $filename): EnchantDictionary|false {}
3131

3232
/** @deprecated */
33-
function enchant_broker_free_dict(EnchantDictionary $dict): bool {}
33+
function enchant_broker_free_dict(EnchantDictionary $dictionary): bool {}
3434

3535
function enchant_broker_dict_exists(EnchantBroker $broker, string $tag): bool {}
3636

@@ -39,32 +39,32 @@ function enchant_broker_set_ordering(EnchantBroker $broker, string $tag, string
3939
function enchant_broker_describe(EnchantBroker $broker): array {}
4040

4141
/** @param array $suggestions */
42-
function enchant_dict_quick_check(EnchantDictionary $dict, string $word, &$suggestions = null): bool {}
42+
function enchant_dict_quick_check(EnchantDictionary $dictionary, string $word, &$suggestions = null): bool {}
4343

44-
function enchant_dict_check(EnchantDictionary $dict, string $word): bool {}
44+
function enchant_dict_check(EnchantDictionary $dictionary, string $word): bool {}
4545

46-
function enchant_dict_suggest(EnchantDictionary $dict, string $word): array {}
46+
function enchant_dict_suggest(EnchantDictionary $dictionary, string $word): array {}
4747

48-
function enchant_dict_add(EnchantDictionary $dict, string $word): void {}
48+
function enchant_dict_add(EnchantDictionary $dictionary, string $word): void {}
4949

5050
/**
5151
* @alias enchant_dict_add
5252
* @deprecated
5353
*/
54-
function enchant_dict_add_to_personal(EnchantDictionary $dict, string $word): void {}
54+
function enchant_dict_add_to_personal(EnchantDictionary $dictionary, string $word): void {}
5555

56-
function enchant_dict_add_to_session(EnchantDictionary $dict, string $word): void {}
56+
function enchant_dict_add_to_session(EnchantDictionary $dictionary, string $word): void {}
5757

58-
function enchant_dict_is_added(EnchantDictionary $dict, string $word): bool {}
58+
function enchant_dict_is_added(EnchantDictionary $dictionary, string $word): bool {}
5959

6060
/**
6161
* @alias enchant_dict_is_added
6262
* @deprecated
6363
*/
64-
function enchant_dict_is_in_session(EnchantDictionary $dict, string $word): bool {}
64+
function enchant_dict_is_in_session(EnchantDictionary $dictionary, string $word): bool {}
6565

66-
function enchant_dict_store_replacement(EnchantDictionary $dict, string $mis, string $cor): void {}
66+
function enchant_dict_store_replacement(EnchantDictionary $dictionary, string $misspelled, string $correct): void {}
6767

68-
function enchant_dict_get_error(EnchantDictionary $dict): string|false {}
68+
function enchant_dict_get_error(EnchantDictionary $dictionary): string|false {}
6969

70-
function enchant_dict_describe(EnchantDictionary $dict): array {}
70+
function enchant_dict_describe(EnchantDictionary $dictionary): array {}

ext/enchant/enchant_arginfo.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 22c47f0b30f6952a42546c403fbd2e92836661fa */
2+
* Stub hash: 31f7c4cd39e58d6474b90acd65f4b7bda7a6ddf3 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_enchant_broker_init, 0, 0, EnchantBroker, MAY_BE_FALSE)
55
ZEND_END_ARG_INFO()
@@ -14,13 +14,13 @@ ZEND_END_ARG_INFO()
1414

1515
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_broker_set_dict_path, 0, 3, _IS_BOOL, 0)
1616
ZEND_ARG_OBJ_INFO(0, broker, EnchantBroker, 0)
17-
ZEND_ARG_TYPE_INFO(0, name, IS_LONG, 0)
18-
ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0)
17+
ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0)
18+
ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0)
1919
ZEND_END_ARG_INFO()
2020

2121
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_enchant_broker_get_dict_path, 0, 2, MAY_BE_STRING|MAY_BE_FALSE)
2222
ZEND_ARG_OBJ_INFO(0, broker, EnchantBroker, 0)
23-
ZEND_ARG_TYPE_INFO(0, name, IS_LONG, 0)
23+
ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0)
2424
ZEND_END_ARG_INFO()
2525

2626
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_broker_list_dicts, 0, 1, IS_ARRAY, 0)
@@ -38,7 +38,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_enchant_broker_request_pwl_d
3838
ZEND_END_ARG_INFO()
3939

4040
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_broker_free_dict, 0, 1, _IS_BOOL, 0)
41-
ZEND_ARG_OBJ_INFO(0, dict, EnchantDictionary, 0)
41+
ZEND_ARG_OBJ_INFO(0, dictionary, EnchantDictionary, 0)
4242
ZEND_END_ARG_INFO()
4343

4444
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_broker_dict_exists, 0, 2, _IS_BOOL, 0)
@@ -55,23 +55,23 @@ ZEND_END_ARG_INFO()
5555
#define arginfo_enchant_broker_describe arginfo_enchant_broker_list_dicts
5656

5757
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_dict_quick_check, 0, 2, _IS_BOOL, 0)
58-
ZEND_ARG_OBJ_INFO(0, dict, EnchantDictionary, 0)
58+
ZEND_ARG_OBJ_INFO(0, dictionary, EnchantDictionary, 0)
5959
ZEND_ARG_TYPE_INFO(0, word, IS_STRING, 0)
6060
ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, suggestions, "null")
6161
ZEND_END_ARG_INFO()
6262

6363
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_dict_check, 0, 2, _IS_BOOL, 0)
64-
ZEND_ARG_OBJ_INFO(0, dict, EnchantDictionary, 0)
64+
ZEND_ARG_OBJ_INFO(0, dictionary, EnchantDictionary, 0)
6565
ZEND_ARG_TYPE_INFO(0, word, IS_STRING, 0)
6666
ZEND_END_ARG_INFO()
6767

6868
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_dict_suggest, 0, 2, IS_ARRAY, 0)
69-
ZEND_ARG_OBJ_INFO(0, dict, EnchantDictionary, 0)
69+
ZEND_ARG_OBJ_INFO(0, dictionary, EnchantDictionary, 0)
7070
ZEND_ARG_TYPE_INFO(0, word, IS_STRING, 0)
7171
ZEND_END_ARG_INFO()
7272

7373
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_dict_add, 0, 2, IS_VOID, 0)
74-
ZEND_ARG_OBJ_INFO(0, dict, EnchantDictionary, 0)
74+
ZEND_ARG_OBJ_INFO(0, dictionary, EnchantDictionary, 0)
7575
ZEND_ARG_TYPE_INFO(0, word, IS_STRING, 0)
7676
ZEND_END_ARG_INFO()
7777

@@ -84,17 +84,17 @@ ZEND_END_ARG_INFO()
8484
#define arginfo_enchant_dict_is_in_session arginfo_enchant_dict_check
8585

8686
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_dict_store_replacement, 0, 3, IS_VOID, 0)
87-
ZEND_ARG_OBJ_INFO(0, dict, EnchantDictionary, 0)
88-
ZEND_ARG_TYPE_INFO(0, mis, IS_STRING, 0)
89-
ZEND_ARG_TYPE_INFO(0, cor, IS_STRING, 0)
87+
ZEND_ARG_OBJ_INFO(0, dictionary, EnchantDictionary, 0)
88+
ZEND_ARG_TYPE_INFO(0, misspelled, IS_STRING, 0)
89+
ZEND_ARG_TYPE_INFO(0, correct, IS_STRING, 0)
9090
ZEND_END_ARG_INFO()
9191

9292
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_enchant_dict_get_error, 0, 1, MAY_BE_STRING|MAY_BE_FALSE)
93-
ZEND_ARG_OBJ_INFO(0, dict, EnchantDictionary, 0)
93+
ZEND_ARG_OBJ_INFO(0, dictionary, EnchantDictionary, 0)
9494
ZEND_END_ARG_INFO()
9595

9696
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_enchant_dict_describe, 0, 1, IS_ARRAY, 0)
97-
ZEND_ARG_OBJ_INFO(0, dict, EnchantDictionary, 0)
97+
ZEND_ARG_OBJ_INFO(0, dictionary, EnchantDictionary, 0)
9898
ZEND_END_ARG_INFO()
9999

100100

0 commit comments

Comments
 (0)