Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Claude

Go read `../AGENTS.md`.
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Agents

## Vulnerability reports

When scanning php-src for vulnerabilities, please respect our security policy
summarized in `./SECURITY.md`. You can find the full policy
[here](https://raw.githubusercontent.com/php/policies/refs/heads/main/security-classification.rst).
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.6.0beta3
?? ??? ????, PHP 8.6.0RC1


10 Sep 2026, PHP 8.6.0beta3

- BCMath:
. Fixed out-of-bounds read in bc_is_zero_for_scale() when scale exceeds
Expand Down
7 changes: 7 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ are not limited to):

- Malicious `unserialize()` inputs.

- Memory exhaustion from a size the input declares, where `memory_limit`
refuses the allocation and only the current request dies.

When creating reports, please **skip** the theatrics. Drop the impact essay,
send a short reproducer with the few lines that matter, and make each point
once. This allows us to triage and respond to your report quickly.

# Vulnerability Policy

Our full policy is described at
Expand Down
16 changes: 8 additions & 8 deletions docs/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ slightly different steps. We'll call attention where the steps differ.
# .
#
git add -p
git add archive/entries/*.xml
git add public/archive/entries/*.xml
git commit --gpg-sign=YOURKEYID -m "Announce PHP X.Y.0RCn"
git push upstream master
```
Expand Down Expand Up @@ -758,9 +758,9 @@ slightly different steps. We'll call attention where the steps differ.
./bin/createReleaseEntry -v X.Y.Z -r # --security for security releases
```

This will create a release file (i.e., `releases/X_Y_Z.php`) and a news entry
file (i.e., `archive/entries/YYYY-MM-DD-n.xml`), while also updating
`archive/archive.xml`.
This will create a release file (i.e., `public/releases/X_Y_Z.php`) and a news
entry file (i.e., `public/archive/entries/YYYY-MM-DD-n.xml`), while also
updating `public/archive/archive.xml`.

Within these files, it will generate standard messages for the new version.
You may edit the generated files to expand on the base message, if needed.
Expand All @@ -776,7 +776,7 @@ slightly different steps. We'll call attention where the steps differ.
for PHP 8.4) added above the first anchor of the previous version.

```shell
./bin/news2html 'https://github.com/php/php-src/raw/php-X.Y.Z/NEWS' 'X.Y.Z' 'ChangeLog-X.php'
./bin/news2html 'https://github.com/php/php-src/raw/php-X.Y.Z/NEWS' 'X.Y.Z' 'public/ChangeLog-X.php'
```
8. Update the information in the `$QA_RELEASES` array in `include/release-qa.php`.

Expand All @@ -792,7 +792,7 @@ slightly different steps. We'll call attention where the steps differ.

```shell
git add -p
git add archive/entries/*.xml releases/*.php
git add public/archive/entries/*.xml public/releases/*.php
git commit --gpg-sign=YOURKEYID -m "Announce PHP X.Y.Z"
git push upstream master
```
Expand Down Expand Up @@ -884,8 +884,8 @@ If you choose to create a patch-level release, follow these steps:
* Call `php bin/createReleaseEntry -v <version> [ --security ]` in your
local web-php checkout.

4. Commit all the changes (`include/version.inc`, `archive/archive.xml`,
`archive/entries/YYYY-MM-DD-N.xml`).
4. Commit all the changes (`include/version.inc`, `public/archive/archive.xml`,
`public/archive/entries/YYYY-MM-DD-N.xml`).

5. Wait an hour or two, then send a mail to php-announce@lists.php.net,
php-general@lists.php.net and internals@lists.php.net with a text similar to
Expand Down
49 changes: 31 additions & 18 deletions ext/odbc/php_odbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,11 +576,31 @@ PHP_MINFO_FUNCTION(odbc)
}
/* }}} */

static SQLRETURN odbc_diag_rec(ODBC_SQL_ENV_T henv, ODBC_SQL_CONN_T conn, ODBC_SQL_STMT_T stmt,
char *state, char *errormsg, SQLSMALLINT errormsg_size)
{
SQLINTEGER native_error;
SQLSMALLINT handle_type;
SQLHANDLE handle;

if (stmt != SQL_NULL_HSTMT) {
handle_type = SQL_HANDLE_STMT;
handle = (SQLHANDLE) stmt;
} else if (conn != SQL_NULL_HDBC) {
handle_type = SQL_HANDLE_DBC;
handle = (SQLHANDLE) conn;
} else {
handle_type = SQL_HANDLE_ENV;
handle = (SQLHANDLE) henv;
}

return SQLGetDiagRec(handle_type, handle, 1, (SQLCHAR *) state, &native_error,
(SQLCHAR *) errormsg, errormsg_size, NULL);
}

/* {{{ odbc_sql_error */
void odbc_sql_error(odbc_connection *conn_resource, ODBC_SQL_STMT_T stmt, const char *func, ...)
{
SQLINTEGER error; /* Not used */
SQLSMALLINT errormsgsize; /* Not used */
RETCODE rc;
ODBC_SQL_ENV_T henv;
ODBC_SQL_CONN_T conn;
Expand All @@ -593,12 +613,7 @@ void odbc_sql_error(odbc_connection *conn_resource, ODBC_SQL_STMT_T stmt, const
conn = SQL_NULL_HDBC;
}

/* This leads to an endless loop in many drivers!
*
while(henv != SQL_NULL_HENV){
do {
*/
rc = SQLError(henv, conn, stmt, (SQLCHAR *) ODBCG(laststate), &error, (SQLCHAR *) ODBCG(lasterrormsg), sizeof(ODBCG(lasterrormsg))-1, &errormsgsize);
rc = odbc_diag_rec(henv, conn, stmt, ODBCG(laststate), ODBCG(lasterrormsg), sizeof(ODBCG(lasterrormsg))-1);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
snprintf(ODBCG(laststate), sizeof(ODBCG(laststate)), "HY000");
snprintf(ODBCG(lasterrormsg), sizeof(ODBCG(lasterrormsg)), "Failed to fetch error message");
Expand All @@ -619,10 +634,6 @@ void odbc_sql_error(odbc_connection *conn_resource, ODBC_SQL_STMT_T stmt, const
} else {
php_error_docref(NULL, E_WARNING, "SQL error: %s, SQL state %s", ODBCG(lasterrormsg), ODBCG(laststate));
}
/*
} while (SQL_SUCCEEDED(rc));
}
*/
}
/* }}} */

Expand Down Expand Up @@ -1161,14 +1172,16 @@ PHP_FUNCTION(odbc_cursor)
cursorname = emalloc(max_len + 1);
rc = SQLGetCursorName(result->stmt, (SQLCHAR *) cursorname, (SQLSMALLINT)max_len, &len);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
char state[6]; /* Not used */
SQLINTEGER error; /* Not used */
char state[6];
char errormsg[SQL_MAX_MESSAGE_LENGTH];
SQLSMALLINT errormsgsize; /* Not used */
SQLRETURN diag_rc;

SQLError( result->conn_ptr->henv, result->conn_ptr->hdbc,
result->stmt, (SQLCHAR *) state, &error, (SQLCHAR *) errormsg,
sizeof(errormsg)-1, &errormsgsize);
diag_rc = odbc_diag_rec(result->conn_ptr->henv, result->conn_ptr->hdbc, result->stmt,
state, errormsg, sizeof(errormsg)-1);
if (diag_rc != SQL_SUCCESS && diag_rc != SQL_SUCCESS_WITH_INFO) {
snprintf(state, sizeof(state), "HY000");
snprintf(errormsg, sizeof(errormsg), "Failed to fetch error message");
}
if (!strncmp(state,"S1015",5)) {
snprintf(cursorname, max_len+1, "php_curs_" ZEND_ULONG_FMT, (zend_ulong)result->stmt);
if (SQLSetCursorName(result->stmt, (SQLCHAR *) cursorname, SQL_NTS) != SQL_SUCCESS) {
Expand Down
5 changes: 4 additions & 1 deletion ext/opcache/jit/ir/ir_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,12 @@ typedef struct _ir_sparse_set {

IR_ALWAYS_INLINE void ir_sparse_set_init(ir_sparse_set *set, uint32_t size)
{
size_t alloc_size = (size_t)size * 2 * sizeof(*set->data);

set->size = size;
set->len = 0;
set->data = (uint32_t*)ir_mem_malloc(sizeof(uint32_t) * 2 * size) + size;
IR_ASSERT(!size || alloc_size / size == 2 * sizeof(*set->data));
set->data = (uint32_t*)ir_mem_malloc(alloc_size) + size;
#ifdef IR_DEBUG
/* initialize sparse part to avoid valgrind warnings */
memset(&IR_SPARSE_SET_SPARSE(set, size - 1), 0, size * sizeof(uint32_t));
Expand Down