Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
cac8f7f
Fix GHSA-3cr5-j632-f35r: Null byte in hostnames
bukka Apr 10, 2025
9376aee
Fix GHSA-hrwm-9436-5mv3: pgsql escaping no error checks
bukka Mar 4, 2025
9cb3d8d
Fix GHSA-453j-q27h-5p8x
Lekssays Jun 3, 2025
7b33b1c
Update NEWS with entries for security fixes
bukka Jun 26, 2025
cf0c397
Fix GHSA-3cr5-j632-f35r: Null byte in hostnames
bukka Apr 10, 2025
545d153
Fix GHSA-hrwm-9436-5mv3: pgsql escaping no error checks
bukka Mar 4, 2025
dd06065
Fix GHSA-453j-q27h-5p8x
Lekssays Jun 3, 2025
fc49d33
Update NEWS with entries for security fixes
bukka Jun 26, 2025
7f5d491
Merge branch 'PHP-8.3' into PHP-8.4
ericmann Jul 1, 2025
50e1b23
Merge branch 'PHP-8.4'
ericmann Jul 1, 2025
27e67cc
Fix GHSA-3cr5-j632-f35r: Null byte in hostnames
bukka Apr 10, 2025
a2cdff5
Fix GHSA-hrwm-9436-5mv3: pgsql escaping no error checks
bukka Mar 4, 2025
0298837
Fix GHSA-453j-q27h-5p8x
Lekssays Jun 3, 2025
165e516
Update NEWS with entries for security fixes
bukka Jun 26, 2025
3d8cc22
PHP-8.2 is now for PHP 8.2.30-dev
saundefined Jul 1, 2025
9174984
Fix OSS-Fuzz #427814456
ndossche Jun 26, 2025
1d5089e
Fix GH-18979: DOM\XMLDocument::createComment() triggers undefined beh…
ndossche Jun 30, 2025
30662e4
Merge branch 'PHP-8.4'
ndossche Jul 1, 2025
5d590a1
Merge branch 'PHP-8.3' into PHP-8.4
ndossche Jul 1, 2025
d706dc1
Merge branch 'PHP-8.4'
ndossche Jul 1, 2025
b576ad4
Merge branch 'PHP-8.2' into PHP-8.3
saundefined Jul 1, 2025
7a3c0d3
Merge branch 'PHP-8.3' into PHP-8.4
saundefined Jul 1, 2025
f71271d
Merge branch 'PHP-8.4'
saundefined Jul 1, 2025
59dd0f8
Zend: Use `zend_bad_method_call()` when cloning from the wrong scope …
TimWolla Jul 1, 2025
6637638
Update uriparser to commit 5f7c6d88c50f548d0c7f499c22d36f51d34775b3
kocsismate Jul 1, 2025
13bc0e2
Merge branch 'PHP-8.1.33-security' into PHP-8.1
ramsey Jul 1, 2025
ca09f4d
PHP-8.1 is now for PHP 8.1.34-dev
ramsey Jul 1, 2025
442638e
Merge branch 'PHP-8.1' into PHP-8.2
ramsey Jul 1, 2025
fa960f7
Merge branch 'PHP-8.2' into PHP-8.3
ramsey Jul 1, 2025
881ec13
Merge branch 'PHP-8.3' into PHP-8.4
ramsey Jul 1, 2025
607eec8
Merge branch 'PHP-8.4'
ramsey Jul 1, 2025
642d729
release-process: update some confusing parts (#18934)
DanielEScherzer Jul 1, 2025
45c4650
[ci skip] Update NEWS for PHP 8.5.0 alpha2
DanielEScherzer Jul 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.5.0alpha1
?? ??? ????, PHP 8.5.0alpha2


03 Jul 2025, PHP 8.5.0alpha1

- BCMath:
. Simplify `bc_divide()` code. (SakiTakamachi)
Expand Down
11 changes: 11 additions & 0 deletions Zend/tests/numeric_strings/oss_fuzz_427814456.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--TEST--
OSS-Fuzz #427814456
--FILE--
<?php
set_error_handler(function(){unset($GLOBALS['x']);});
$x = str_repeat("3e33", random_int(2, 2));
$x & true;
echo "Done\n";
?>
--EXPECT--
Done
6 changes: 1 addition & 5 deletions Zend/zend_builtin_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,7 @@ ZEND_FUNCTION(clone)
if (clone->common.scope != scope) {
if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
zend_throw_error(NULL, "Call to %s %s::__clone() from %s%s",
zend_visibility_string(clone->common.fn_flags), ZSTR_VAL(clone->common.scope->name),
scope ? "scope " : "global scope",
scope ? ZSTR_VAL(scope->name) : ""
);
zend_bad_method_call(clone, clone->common.function_name, scope);
RETURN_THROWS();
}
}
Expand Down
9 changes: 0 additions & 9 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -4123,15 +4123,6 @@ static zend_never_inline void zend_fetch_this_var(int type OPLINE_DC EXECUTE_DAT
}
}

static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_wrong_clone_call(zend_function *clone, zend_class_entry *scope)
{
zend_throw_error(NULL, "Call to %s %s::__clone() from %s%s",
zend_visibility_string(clone->common.fn_flags), ZSTR_VAL(clone->common.scope->name),
scope ? "scope " : "global scope",
scope ? ZSTR_VAL(scope->name) : ""
);
}

#if ZEND_INTENSIVE_DEBUGGING

#define CHECK_SYMBOL_TABLES() \
Expand Down
7 changes: 6 additions & 1 deletion Zend/zend_operators.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
zend_long lval;
double dval;
bool trailing_data = false;
zend_string *op_str = NULL; /* protect against error handlers */

/* For BC reasons we allow errors so that we can warn on leading numeric string */
type = is_numeric_string_ex(Z_STRVAL_P(op), Z_STRLEN_P(op), &lval, &dval,
Expand All @@ -411,6 +412,9 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
return 0;
}
if (UNEXPECTED(trailing_data)) {
if (type != IS_LONG) {
op_str = zend_string_copy(Z_STR_P(op));
}
zend_error(E_WARNING, "A non-numeric value encountered");
if (UNEXPECTED(EG(exception))) {
*failed = 1;
Expand All @@ -426,11 +430,12 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
*/
lval = zend_dval_to_lval_cap(dval);
if (!zend_is_long_compatible(dval, lval)) {
zend_incompatible_string_to_long_error(Z_STR_P(op));
zend_incompatible_string_to_long_error(op_str ? op_str : Z_STR_P(op));
if (UNEXPECTED(EG(exception))) {
*failed = 1;
}
}
zend_tmp_string_release(op_str);
return lval;
}
}
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -6046,7 +6046,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
if (clone->common.scope != scope) {
if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
zend_wrong_clone_call(clone, scope);
zend_bad_method_call(clone, clone->common.function_name, scope);
FREE_OP1();
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
Expand Down
8 changes: 4 additions & 4 deletions Zend/zend_vm_execute.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 23 additions & 4 deletions docs/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ slightly different steps. We'll call attention where the steps differ.
4. Using your local-only release branch, bump the version numbers in
`main/php_version.h`, `Zend/zend.h`, `configure.ac`, and possibly
`NEWS`.


The date for NEWS should be the date of the announcement (Thursday),
*not* the date of the tagging (Tuesday).

For examples, see [Update versions for PHP 8.1.0beta3][] (for a pre-GA
example) or [Update versions for PHP 8.1.6RC1][] along with
[Update NEWS for PHP 8.1.6RC1][] (for a post-GA example).
Expand Down Expand Up @@ -250,6 +253,9 @@ slightly different steps. We'll call attention where the steps differ.
git commit --gpg-sign=YOURKEYID -m "[ci skip] Update NEWS for PHP X.Y.Z alpha2"
```

The NEWS is updated at the *start* of the cycle for the next tag, e.g.
[Update NEWS for PHP 8.2.0 alpha2][] was sent as part of tagging 8.2.0 alpha **1**.

🔷 **For post-GA releases only,** switch back to the *version branch* for
your release (e.g., `PHP-8.2`) and bump the version numbers in
`main/php_version.h`, `Zend/zend.h`, `configure.ac` and `NEWS`. This prepares
Expand Down Expand Up @@ -365,6 +371,10 @@ slightly different steps. We'll call attention where the steps differ.

Follow the documentation in the file for editing the QA release information.

> 🚨 **Attention** \
> **For pre-GA releases only,** don't commit yet, because you need to add an
> announcement with the release. After updating `$QA_RELEASES`, skip to step 2 below.

Add, commit, and push your changes, when finished.

```shell
Expand Down Expand Up @@ -408,6 +418,15 @@ slightly different steps. We'll call attention where the steps differ.
text slightly to indicate progression through the pre-release cycle. For
example, here are all the news posts for the pre-GA releases of PHP 8.1.0:

> 💬 **Hint** \
> If you are going to base your language on one of these old announcements,
> remember that
> * `qa.php.net` has been replaced with https://www.php.net/release-candidates.php
> * `bugs.php.net` has been replaced with GitHub issues, use
> `https://github.com/php/php-src/issues/new?template=bug_report.yml`
> to link directly to the form for creating a new bug report.
> * Since 8.4 there have only been 4 release candidates for PHP X.Y.0, rather than 6.

* [Announce 8.1.0alpha1](https://github.com/php/web-php/commit/57b9675c8d8550493289fa1fba77427c93cdd472)
* [Announce 8.1.0alpha2](https://github.com/php/web-php/commit/cec044fc0763f5cfa77d0e79479f8b6279023570)
* [Announce 8.1.0alpha3](https://github.com/php/web-php/commit/5c480765f444a3fddfd575e01fe0be3fcfdde05b)
Expand All @@ -431,7 +450,7 @@ slightly different steps. We'll call attention where the steps differ.
> When a version is in its post-GA phase, we do not post news entries for
> non-stable releases.

3. Wait for the web and qa sites to update with the new information before
3. Wait for the php site to update with the new information before
sending announcements. This could take up to an hour.

4. Send *separate* announcement emails to:
Expand Down Expand Up @@ -720,10 +739,10 @@ slightly different steps. We'll call attention where the steps differ.

The array probably contains information about the RC released two weeks ago
in preparation for the current release. Since the current release is now GA,
it's time to remove the RC build from the QA website.
it's time to remove the RC build from the release candidates page.

It is sufficient to set the `number` property for the release to `0` to
stop displaying the RC build on the QA website. You may also remove the
stop displaying the RC build on the release candidates page. You may also remove the
sha256 hashes for the RC tarballs, but it's not necessary.

9. Review all the changes in `web-php`, commit, and push them.
Expand Down
13 changes: 13 additions & 0 deletions ext/dom/tests/modern/xml/gh18979.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
GH-18979 (DOM\XMLDocument::createComment() triggers undefined behavior with null byte)
--EXTENSIONS--
dom
--FILE--
<?php
$dom = Dom\XMLDocument::createEmpty();
$container = $dom->createElement("container");
$container->append($dom->createComment("\0"));
var_dump($container->innerHTML);
?>
--EXPECT--
string(7) "<!---->"
6 changes: 5 additions & 1 deletion ext/dom/xml_serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,11 @@ static int dom_xml_serialize_comment_node(xmlOutputBufferPtr out, xmlNodePtr com
const xmlChar *ptr = comment->content;
if (ptr != NULL) {
TRY(dom_xml_check_char_production(ptr));
if (strstr((const char *) ptr, "--") != NULL || ptr[strlen((const char *) ptr) - 1] == '-') {
if (strstr((const char *) ptr, "--") != NULL) {
return -1;
}
size_t len = strlen((const char *) ptr);
if (len > 0 && ptr[len - 1] == '-') {
return -1;
}
}
Expand Down
4 changes: 2 additions & 2 deletions ext/uri/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ AC_DEFINE([URI_ENABLE_ANSI], [1], [Define to 1 for enabling ANSI support of urip
AC_DEFINE([URI_NO_UNICODE], [1], [Define to 1 for disabling unicode support of uriparser.])

URIPARSER_DIR="uriparser"
URIPARSER_SOURCES="$URIPARSER_DIR/src/UriCommon.c $URIPARSER_DIR/src/UriCompare.c $URIPARSER_DIR/src/UriEscape.c \
$URIPARSER_DIR/src/UriFile.c $URIPARSER_DIR/src/UriIp4.c $URIPARSER_DIR/src/UriIp4Base.c \
URIPARSER_SOURCES="$URIPARSER_DIR/src/UriCommon.c $URIPARSER_DIR/src/UriCompare.c $URIPARSER_DIR/src/UriCopy.c \
$URIPARSER_DIR/src/UriEscape.c $URIPARSER_DIR/src/UriFile.c $URIPARSER_DIR/src/UriIp4.c $URIPARSER_DIR/src/UriIp4Base.c \
$URIPARSER_DIR/src/UriMemory.c $URIPARSER_DIR/src/UriNormalize.c $URIPARSER_DIR/src/UriNormalizeBase.c \
$URIPARSER_DIR/src/UriParse.c $URIPARSER_DIR/src/UriParseBase.c $URIPARSER_DIR/src/UriQuery.c \
$URIPARSER_DIR/src/UriRecompose.c $URIPARSER_DIR/src/UriResolve.c $URIPARSER_DIR/src/UriShorten.c"
Expand Down
2 changes: 1 addition & 1 deletion ext/uri/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ AC_DEFINE("URI_NO_UNICODE", 1, "Define to 1 for disabling unicode support of uri
ADD_FLAG("CFLAGS_URI", "/D URI_STATIC_BUILD");

ADD_EXTENSION_DEP('uri', 'lexbor');
ADD_SOURCES("ext/uri/uriparser/src", "UriCommon.c UriCompare.c UriEscape.c UriFile.c UriIp4.c UriIp4Base.c UriMemory.c UriNormalize.c UriNormalizeBase.c UriParse.c UriParseBase.c UriQuery.c UriRecompose.c UriShorten.c", "uri");
ADD_SOURCES("ext/uri/uriparser/src", "UriCommon.c UriCompare.c UriCopy.c UriEscape.c UriFile.c UriIp4.c UriIp4Base.c UriMemory.c UriNormalize.c UriNormalizeBase.c UriParse.c UriParseBase.c UriQuery.c UriRecompose.c UriResolve.c UriShorten.c", "uri");
PHP_INSTALL_HEADERS("ext/uri", "php_lexbor.h php_uri.h php_uri_common.h uriparser/src uriparser/include");
41 changes: 41 additions & 0 deletions ext/uri/uriparser/include/uriparser/Uri.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,17 @@ typedef struct URI_TYPE(QueryListStruct) {
} URI_TYPE(QueryList); /**< @copydoc UriQueryListStructA */


/**
* Checks if a URI has the host component set.
*
* @param uri <b>IN</b>: %URI to check
* @return <c>URI_TRUE</c> when host is set, <c>URI_FALSE</c> otherwise
*
* @since 0.9.9
*/
URI_PUBLIC UriBool URI_FUNC(HasHost)(const URI_TYPE(Uri) * uri);



/**
* Parses a RFC 3986 %URI.
Expand Down Expand Up @@ -644,6 +655,36 @@ URI_PUBLIC int URI_FUNC(ToString)(URI_CHAR * dest, const URI_TYPE(Uri) * uri,



/**
* Copies a %URI structure.
*
* @param destUri <b>OUT</b>: Output destination
* @param sourceUri <b>IN</b>: %URI to copy
* @param memory <b>IN</b>: Memory manager to use, NULL for default libc
* @return Error code or 0 on success
*
* @see uriCopyUriA
* @since 0.9.9
*/
URI_PUBLIC int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri,
const URI_TYPE(Uri) * sourceUri, UriMemoryManager * memory);



/**
* Copies a %URI structure.
*
* @param destUri <b>OUT</b>: Output destination
* @param sourceUri <b>IN</b>: %URI to copy
* @return Error code or 0 on success
*
* @see uriCopyUriMmA
* @since 0.9.9
*/
URI_PUBLIC int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri, const URI_TYPE(Uri) * sourceUri);



/**
* Determines the components of a %URI that are not normalized.
*
Expand Down
3 changes: 2 additions & 1 deletion ext/uri/uriparser/include/uriparser/UriBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ typedef enum UriNormalizationMaskEnum {
URI_NORMALIZE_HOST = 1 << 2, /**< Normalize host (fix uppercase letters) */
URI_NORMALIZE_PATH = 1 << 3, /**< Normalize path (fix uppercase percent-encodings and redundant dot segments) */
URI_NORMALIZE_QUERY = 1 << 4, /**< Normalize query (fix uppercase percent-encodings) */
URI_NORMALIZE_FRAGMENT = 1 << 5 /**< Normalize fragment (fix uppercase percent-encodings) */
URI_NORMALIZE_FRAGMENT = 1 << 5, /**< Normalize fragment (fix uppercase percent-encodings) */
URI_NORMALIZE_PORT = 1 << 6 /**< Normalize port (drop leading zeros) @since 0.9.9 */
} UriNormalizationMask; /**< @copydoc UriNormalizationMaskEnum */


Expand Down
40 changes: 37 additions & 3 deletions ext/uri/uriparser/src/UriCommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,40 @@ int URI_FUNC(CompareRange)(



UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange,
const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory) {
const int lenInChars = (int)(sourceRange->afterLast - sourceRange->first);
const int lenInBytes = lenInChars * sizeof(URI_CHAR);
URI_CHAR * dup = memory->malloc(memory, lenInBytes);
if (dup == NULL) {
return URI_FALSE;
}
memcpy(dup, sourceRange->first, lenInBytes);
destRange->first = dup;
destRange->afterLast = dup + lenInChars;

return URI_TRUE;
}



UriBool URI_FUNC(CopyRangeAsNeeded)(URI_TYPE(TextRange) * destRange,
const URI_TYPE(TextRange) * sourceRange, UriBool useSafe, UriMemoryManager * memory) {
if (sourceRange->first == NULL) {
destRange->first = NULL;
destRange->afterLast = NULL;
} else if (sourceRange->first == sourceRange->afterLast && useSafe) {
destRange->first = URI_FUNC(SafeToPointTo);
destRange->afterLast = URI_FUNC(SafeToPointTo);
} else {
return URI_FUNC(CopyRange)(destRange, sourceRange, memory);
}

return URI_TRUE;
}



UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,
UriBool relative, UriBool pathOwned, UriMemoryManager * memory) {
URI_TYPE(PathSegment) * walker;
Expand Down Expand Up @@ -189,7 +223,7 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,

if (prev == NULL) {
/* Last and first */
if (URI_FUNC(IsHostSet)(uri)) {
if (URI_FUNC(HasHost)(uri)) {
/* Replace "." with empty segment to represent trailing slash */
walker->text.first = URI_FUNC(SafeToPointTo);
walker->text.afterLast = URI_FUNC(SafeToPointTo);
Expand Down Expand Up @@ -463,7 +497,7 @@ URI_CHAR URI_FUNC(HexToLetterEx)(unsigned int value, UriBool uppercase) {


/* Checks if a URI has the host component set. */
UriBool URI_FUNC(IsHostSet)(const URI_TYPE(Uri) * uri) {
UriBool URI_FUNC(HasHost)(const URI_TYPE(Uri) * uri) {
return (uri != NULL)
&& ((uri->hostText.first != NULL)
|| (uri->hostData.ip4 != NULL)
Expand Down Expand Up @@ -601,7 +635,7 @@ void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri,
UriMemoryManager * memory) {
/* Fix path if only one empty segment */
if (!uri->absolutePath
&& !URI_FUNC(IsHostSet)(uri)
&& !URI_FUNC(HasHost)(uri)
&& (uri->pathHead != NULL)
&& (uri->pathHead->next == NULL)
&& (uri->pathHead->text.first == uri->pathHead->text.afterLast)) {
Expand Down
7 changes: 5 additions & 2 deletions ext/uri/uriparser/src/UriCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ int URI_FUNC(CompareRange)(
const URI_TYPE(TextRange) * a,
const URI_TYPE(TextRange) * b);

UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange,
const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory);
UriBool URI_FUNC(CopyRangeAsNeeded)(URI_TYPE(TextRange) * destRange,
const URI_TYPE(TextRange) * sourceRange, UriBool useSafe, UriMemoryManager * memory);

UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri,
UriMemoryManager * memory);
UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,
Expand All @@ -91,8 +96,6 @@ unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig);
URI_CHAR URI_FUNC(HexToLetter)(unsigned int value);
URI_CHAR URI_FUNC(HexToLetterEx)(unsigned int value, UriBool uppercase);

UriBool URI_FUNC(IsHostSet)(const URI_TYPE(Uri) * uri);

UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source,
UriMemoryManager * memory);
UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest,
Expand Down
Loading