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
25 changes: 25 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,34 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.6.0alpha2

- DBA:
. Fixed OOB read on malformed length field in dba flatfile handler. (alhudz)

- Exif:
. Fixed bug GH-11020 (exif_read_data() emits a spurious "Illegal IFD size"
warning when an IFD is not followed by a next-IFD offset). (Eyüp Can Akman)

- Opcache:
. Fixed bug GH-21770 (Infinite recursion in property hook getter in opcache
preloaded trait). (iliaal)

- OpenSSL:
. Fixed timeout for supplemental read at end of a blocking stream in SSL
stream wrapper. (ilutov)
. Fixed stream_socket_get_crypto_status() after supplemental read. (ilutov)

- PDO_ODBC:
. Fixed bug GH-20726 (Crash with ODBC connection pooling when the DSN
carries no credentials). (iliaal)

- Session:
. Fixed bug GH-21314 (Different session garbage collector behavior between
PHP 8.3 and PHP 8.5). (jorgsowa)

- Streams:
. Fixed bug GH-21468 (Segfault in file_get_contents w/ a https URL
and a proxy set). (CVE-2026-12184) (ndossche)

02 Jul 2026, PHP 8.6.0alpha1

- Core:
Expand Down
4 changes: 1 addition & 3 deletions ext/dba/dba.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,10 +1282,8 @@ PHP_FUNCTION(dba_handlers)

for (const dba_handler *hptr = handler; hptr->name; hptr++) {
if (full_info) {
// TODO: avoid reallocation ???
char *str = hptr->info(hptr, NULL);
const char *str = hptr->info(hptr, NULL);
add_assoc_string(return_value, hptr->name, str);
efree(str);
} else {
add_next_index_string(return_value, hptr->name);
}
Expand Down
6 changes: 3 additions & 3 deletions ext/dba/dba_cdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,12 +319,12 @@ DBA_INFO_FUNC(cdb)
{
#ifdef DBA_CDB_BUILTIN
if (!strcmp(hnd->name, "cdb")) {
return estrdup(cdb_version());
return cdb_version();
} else {
return estrdup(cdb_make_version());
return cdb_make_version();
}
#else
return estrdup("External");
return "External";
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion ext/dba/dba_db1.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ DBA_SYNC_FUNC(db1)

DBA_INFO_FUNC(db1)
{
return estrdup(DB1_VERSION);
return DB1_VERSION;
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_db2.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ DBA_SYNC_FUNC(db2)

DBA_INFO_FUNC(db2)
{
return estrdup(DB_VERSION_STRING);
return DB_VERSION_STRING;
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_db3.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ DBA_SYNC_FUNC(db3)

DBA_INFO_FUNC(db3)
{
return estrdup(DB_VERSION_STRING);
return DB_VERSION_STRING;
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_db4.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ DBA_SYNC_FUNC(db4)

DBA_INFO_FUNC(db4)
{
return estrdup(DB_VERSION_STRING);
return DB_VERSION_STRING;
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_dbm.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ DBA_INFO_FUNC(dbm)
return dba_info_gdbm(hnd, info);
}
#endif
return estrdup(DBM_VERSION);
return DBM_VERSION;
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_flatfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ DBA_SYNC_FUNC(flatfile)

DBA_INFO_FUNC(flatfile)
{
return estrdup(flatfile_version());
return flatfile_version();
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_gdbm.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ DBA_SYNC_FUNC(gdbm)

DBA_INFO_FUNC(gdbm)
{
return estrdup(gdbm_version);
return gdbm_version;
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_inifile.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ DBA_SYNC_FUNC(inifile)

DBA_INFO_FUNC(inifile)
{
return estrdup(inifile_version());
return inifile_version();
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_lmdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ DBA_SYNC_FUNC(lmdb)

DBA_INFO_FUNC(lmdb)
{
return estrdup(MDB_VERSION_STRING);
return MDB_VERSION_STRING;
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_ndbm.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ DBA_SYNC_FUNC(ndbm)

DBA_INFO_FUNC(ndbm)
{
return estrdup("NDBM");
return "NDBM";
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_qdbm.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ DBA_SYNC_FUNC(qdbm)

DBA_INFO_FUNC(qdbm)
{
return estrdup(dpversion);
return dpversion;
}

#endif
2 changes: 1 addition & 1 deletion ext/dba/dba_tcadb.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ DBA_SYNC_FUNC(tcadb)

DBA_INFO_FUNC(tcadb)
{
return estrdup(tcversion);
return tcversion;
}

#endif
60 changes: 28 additions & 32 deletions ext/dba/libflatfile/flatfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@

#define FLATFILE_BLOCK_SIZE 1024

/* Parse the length prefix in `buf` into `num` and grow `buf` to hold it.
* atoi() narrows a malformed (e.g. negative) length to a huge size_t whose
* `+ FLATFILE_BLOCK_SIZE` would overflow erealloc(); the macro yields true in
* that case so the caller stops reading and the read stays within `buf_size`. */
#define FLATFILE_GROW_BUF(num, buf, buf_size) ( \
(num) = atoi(buf), \
(num) >= (buf_size) && ( \
(num) > SIZE_MAX - FLATFILE_BLOCK_SIZE \
|| ((buf) = erealloc((buf), (buf_size) = (num) + FLATFILE_BLOCK_SIZE), 0) \
) \
)

/*
* ret = -1 means that database was opened for read-only
* ret = 0 success
Expand Down Expand Up @@ -110,10 +122,8 @@ int flatfile_delete(flatfile *dba, datum key_datum) {
if (!php_stream_gets(dba->fp, buf, 15)) {
break;
}
num = atoi(buf);
if (num >= buf_size) {
buf_size = num + FLATFILE_BLOCK_SIZE;
buf = erealloc(buf, buf_size);
if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
break;
}
pos = php_stream_tell(dba->fp);

Expand All @@ -133,10 +143,8 @@ int flatfile_delete(flatfile *dba, datum key_datum) {
if (!php_stream_gets(dba->fp, buf, 15)) {
break;
}
num = atoi(buf);
if (num >= buf_size) {
buf_size = num + FLATFILE_BLOCK_SIZE;
buf = erealloc(buf, buf_size);
if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
break;
}
/* read in the value */
num = php_stream_read(dba->fp, buf, num);
Expand All @@ -160,10 +168,8 @@ int flatfile_findkey(flatfile *dba, datum key_datum) {
if (!php_stream_gets(dba->fp, buf, 15)) {
break;
}
num = atoi(buf);
if (num >= buf_size) {
buf_size = num + FLATFILE_BLOCK_SIZE;
buf = erealloc(buf, buf_size);
if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
break;
}
num = php_stream_read(dba->fp, buf, num);

Expand All @@ -176,10 +182,8 @@ int flatfile_findkey(flatfile *dba, datum key_datum) {
if (!php_stream_gets(dba->fp, buf, 15)) {
break;
}
num = atoi(buf);
if (num >= buf_size) {
buf_size = num + FLATFILE_BLOCK_SIZE;
buf = erealloc(buf, buf_size);
if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
break;
}
num = php_stream_read(dba->fp, buf, num);
}
Expand All @@ -200,10 +204,8 @@ datum flatfile_firstkey(flatfile *dba) {
if (!php_stream_gets(dba->fp, buf, 15)) {
break;
}
num = atoi(buf);
if (num >= buf_size) {
buf_size = num + FLATFILE_BLOCK_SIZE;
buf = erealloc(buf, buf_size);
if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
break;
}
num = php_stream_read(dba->fp, buf, num);

Expand All @@ -216,10 +218,8 @@ datum flatfile_firstkey(flatfile *dba) {
if (!php_stream_gets(dba->fp, buf, 15)) {
break;
}
num = atoi(buf);
if (num >= buf_size) {
buf_size = num + FLATFILE_BLOCK_SIZE;
buf = erealloc(buf, buf_size);
if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
break;
}
num = php_stream_read(dba->fp, buf, num);
}
Expand All @@ -242,20 +242,16 @@ datum flatfile_nextkey(flatfile *dba) {
if (!php_stream_gets(dba->fp, buf, 15)) {
break;
}
num = atoi(buf);
if (num >= buf_size) {
buf_size = num + FLATFILE_BLOCK_SIZE;
buf = erealloc(buf, buf_size);
if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
break;
}
num = php_stream_read(dba->fp, buf, num);

if (!php_stream_gets(dba->fp, buf, 15)) {
break;
}
num = atoi(buf);
if (num >= buf_size) {
buf_size = num + FLATFILE_BLOCK_SIZE;
buf = erealloc(buf, buf_size);
if (FLATFILE_GROW_BUF(num, buf, buf_size)) {
break;
}
num = php_stream_read(dba->fp, buf, num);

Expand Down
4 changes: 2 additions & 2 deletions ext/dba/php_dba.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ typedef struct dba_handler {
zend_string* (*nextkey)(dba_info *);
zend_result (*optimize)(dba_info *);
zend_result (*sync)(dba_info *);
char* (*info)(const struct dba_handler *hnd, dba_info *);
const char* (*info)(const struct dba_handler *hnd, dba_info *);
/* dba_info==NULL: Handler info, dba_info!=NULL: Database info */
} dba_handler;

Expand All @@ -116,7 +116,7 @@ typedef struct dba_handler {
#define DBA_SYNC_FUNC(x) \
zend_result dba_sync_##x(dba_info *info)
#define DBA_INFO_FUNC(x) \
char *dba_info_##x(const dba_handler *hnd, dba_info *info)
const char *dba_info_##x(const dba_handler *hnd, dba_info *info)

#define DBA_FUNCS(x) \
DBA_OPEN_FUNC(x); \
Expand Down
31 changes: 31 additions & 0 deletions ext/dba/tests/dba_flatfile_oob.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--TEST--
DBA FlatFile handler bounds with a malformed (negative) length field
--EXTENSIONS--
dba
--SKIPIF--
<?php
require_once __DIR__ . '/setup/setup_dba_tests.inc';
check_skip('flatfile');
?>
--FILE--
<?php
$db_file = __DIR__ . '/dba_flatfile_oob.db';
// A negative length narrows to a huge size_t and previously overran the read buffer.
file_put_contents($db_file, "-1\n" . str_repeat('A', 200000));

$db = dba_open($db_file, 'r', 'flatfile');
var_dump(dba_firstkey($db));
var_dump(dba_exists("AAAA", $db));
var_dump(dba_fetch("AAAA", $db));
dba_close($db);
echo "done\n";
?>
--CLEAN--
<?php
@unlink(__DIR__ . '/dba_flatfile_oob.db');
?>
--EXPECT--
bool(false)
bool(false)
bool(false)
done
10 changes: 8 additions & 2 deletions ext/exif/exif.c
Original file line number Diff line number Diff line change
Expand Up @@ -3650,8 +3650,14 @@ static bool exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start
* There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202) to the thumbnail
*/
if (!exif_offset_info_contains(info, dir_start+2+NumDirEntries*12, 4)) {
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size");
return false;
/*
* A TIFF/EXIF IFD ends with a 4-byte offset to the next IFD (IFD1 here,
* which links the thumbnail), or zero when there is none. Some files end
* the EXIF segment right after the entries and omit those 4 bytes. A
* missing offset is valid and just means there is no next IFD, so stop
* here instead of reporting the size as illegal.
*/
return true;
}

if (tag != TAG_EXIF_IFD_POINTER && tag != TAG_GPS_IFD_POINTER) {
Expand Down
2 changes: 0 additions & 2 deletions ext/exif/tests/bug72094.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illega

Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Illegal IFD size in %s%ebug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): File structure corrupted in %s%ebug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Invalid JPEG file in %s%ebug72094.php on line %d
Expand Down
Binary file added ext/exif/tests/gh11020.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions ext/exif/tests/gh11020.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
GH-11020 (exif_read_data() emits a spurious "Illegal IFD size" warning when an IFD is not followed by a next-IFD offset)
--EXTENSIONS--
exif
--FILE--
<?php
$data = exif_read_data(__DIR__ . '/gh11020.jpg');
var_dump(is_array($data), $data['Orientation']);
?>
--EXPECT--
bool(true)
int(1)
1 change: 1 addition & 0 deletions ext/session/php_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ typedef struct _php_ps_globals {
bool mod_user_is_open;
bool mod_user_uses_object_methods_as_handlers;
bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
bool random_seeded;
} php_ps_globals;

typedef php_ps_globals zend_ps_globals;
Expand Down
Loading