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
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ PHP NEWS
. Fixed bug GH-21221 (Prevent closing of innerstream of php://temp stream).
(ilutov)
. Improved stream_socket_server() bind failure error reporting. (ilutov)
. Fixed bug #49874 (ftell() and fseek() inconsistency when using stream
filters). (Jakub Zelenka)

- Zip:
. Fixed ZipArchive callback being called after executor has shut down.
Expand Down
9 changes: 9 additions & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ PHP 8.6 INTERNALS UPGRADE NOTES
longer is a pointer, but a directly embedded HashTable struct.
. Added a C23_ENUM() helper macro to define forward-compatible fixed-size
enums.
. Extended php_stream_filter_ops with seek method.
. The INI_STR(), INI_INT(), INI_FLT(), and INI_BOOL() macros have been
removed. Instead new zend_ini_{bool|long|double|str|string}_literal()
macros have been added. This fixes an internal naming inconsistency as
"str" usually means zend_string*, and "string" means char*.
However INI_STR() returned a char*
. The INI_ORIG_{INT|STR|FLT|BOOL}() macros have been removed as they are
unused. If this behaviour is required fall back to the zend_ini_*
functions.

========================
2. Build system changes
Expand Down
6 changes: 3 additions & 3 deletions Zend/zend_fibers.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,9 +572,9 @@ static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer)
zend_fiber *fiber = EG(active_fiber);

/* Determine the current error_reporting ini setting. */
zend_long error_reporting = INI_INT("error_reporting");
/* If error_reporting is 0 and not explicitly set to 0, INI_STR returns a null pointer. */
if (!error_reporting && !INI_STR("error_reporting")) {
zend_long error_reporting = zend_ini_long_literal("error_reporting");
/* If error_reporting is 0 and not explicitly set to 0, zend_ini_str returns a null pointer. */
if (!error_reporting && !zend_ini_str_literal("error_reporting")) {
error_reporting = E_ALL;
}

Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_highlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
{
zval token;
int token_type;
char *last_color = syntax_highlighter_ini->highlight_html;
char *next_color;
const char *last_color = syntax_highlighter_ini->highlight_html;
const char *next_color;

zend_printf("<pre><code style=\"color: %s\">", last_color);
/* highlight stuff coming back from zendlex() */
Expand Down
10 changes: 5 additions & 5 deletions Zend/zend_highlight.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@


typedef struct _zend_syntax_highlighter_ini {
char *highlight_html;
char *highlight_comment;
char *highlight_default;
char *highlight_string;
char *highlight_keyword;
const char *highlight_html;
const char *highlight_comment;
const char *highlight_default;
const char *highlight_string;
const char *highlight_keyword;
} zend_syntax_highlighter_ini;


Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_ini.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,15 +491,15 @@ ZEND_API double zend_ini_double(const char *name, size_t name_length, bool orig)
}
/* }}} */

ZEND_API char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists) /* {{{ */
ZEND_API const char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists) /* {{{ */
{
zend_string *str = zend_ini_str_ex(name, name_length, orig, exists);

return str ? ZSTR_VAL(str) : NULL;
}
/* }}} */

ZEND_API char *zend_ini_string(const char *name, size_t name_length, bool orig) /* {{{ */
ZEND_API const char *zend_ini_string(const char *name, size_t name_length, bool orig) /* {{{ */
{
zend_string *str = zend_ini_str(name, name_length, orig);

Expand Down
20 changes: 8 additions & 12 deletions Zend/zend_ini.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,19 @@ ZEND_API void display_ini_entries(zend_module_entry *module);

ZEND_API zend_long zend_ini_long(const char *name, size_t name_length, bool orig);
ZEND_API double zend_ini_double(const char *name, size_t name_length, bool orig);
ZEND_API char *zend_ini_string(const char *name, size_t name_length, bool orig);
ZEND_API char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists);
ZEND_API const char *zend_ini_string(const char *name, size_t name_length, bool orig);
ZEND_API const char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists);
ZEND_API zend_string *zend_ini_str(const char *name, size_t name_length, bool orig);
ZEND_API zend_string *zend_ini_str_ex(const char *name, size_t name_length, bool orig, bool *exists);
ZEND_API zend_string *zend_ini_get_value(zend_string *name);
ZEND_API bool zend_ini_parse_bool(const zend_string *str);

#define zend_ini_bool_literal(name) zend_ini_parse_bool(zend_ini_str((name), sizeof("" name) - 1, false))
#define zend_ini_long_literal(name) zend_ini_long((name), sizeof("" name) - 1, false)
#define zend_ini_double_literal(name) zend_ini_double((name), sizeof("" name) - 1, false)
#define zend_ini_str_literal(name) zend_ini_str((name), sizeof("" name) - 1, false)
#define zend_ini_string_literal(name) zend_ini_string((name), sizeof("" name) - 1, false)

/**
* Parses an ini quantity
*
Expand Down Expand Up @@ -191,16 +197,6 @@ END_EXTERN_C()
ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr, NULL, zend_ini_boolean_displayer_cb)
#endif

#define INI_INT(name) zend_ini_long((name), strlen(name), 0)
#define INI_FLT(name) zend_ini_double((name), strlen(name), 0)
#define INI_STR(name) zend_ini_string_ex((name), strlen(name), 0, NULL)
#define INI_BOOL(name) ((bool) INI_INT(name))

#define INI_ORIG_INT(name) zend_ini_long((name), strlen(name), 1)
#define INI_ORIG_FLT(name) zend_ini_double((name), strlen(name), 1)
#define INI_ORIG_STR(name) zend_ini_string((name), strlen(name), 1)
#define INI_ORIG_BOOL(name) ((bool) INI_ORIG_INT(name))

#define REGISTER_INI_ENTRIES() zend_register_ini_entries_ex(ini_entries, module_number, type)
#define UNREGISTER_INI_ENTRIES() zend_unregister_ini_entries_ex(module_number, type)
#define DISPLAY_INI_ENTRIES() display_ini_entries(zend_module)
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_multibyte.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ ZEND_API zend_result zend_multibyte_set_functions(const zend_multibyte_functions
* populated, we need to reinitialize script_encoding here.
*/
{
const char *value = zend_ini_string("zend.script_encoding", sizeof("zend.script_encoding") - 1, 0);
zend_multibyte_set_script_encoding_by_string(value, strlen(value));
const zend_string *value = zend_ini_str_literal("zend.script_encoding");
zend_multibyte_set_script_encoding_by_string(ZSTR_VAL(value), ZSTR_LEN(value));
}
return SUCCESS;
}
Expand Down
79 changes: 77 additions & 2 deletions ext/bz2/bz2_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ typedef struct _php_bz2_filter_data {
unsigned int is_flushed : 1; /* only for compression */

int persistent;

/* Configuration for reset - immutable */
int blockSize100k; /* compress only */
int workFactor; /* compress only */
} php_bz2_filter_data;

/* }}} */
Expand Down Expand Up @@ -178,6 +182,36 @@ static php_stream_filter_status_t php_bz2_decompress_filter(
return exit_status;
}

static zend_result php_bz2_decompress_seek(
php_stream *stream,
php_stream_filter *thisfilter,
zend_off_t offset,
int whence
)
{
if (!Z_PTR(thisfilter->abstract)) {
return FAILURE;
}

php_bz2_filter_data *data = Z_PTR(thisfilter->abstract);

/* End current decompression if running */
if (data->status == PHP_BZ2_RUNNING) {
BZ2_bzDecompressEnd(&(data->strm));
}

/* Reset stream state */
data->strm.next_in = data->inbuf;
data->strm.avail_in = 0;
data->strm.next_out = data->outbuf;
data->strm.avail_out = data->outbuf_len;
data->status = PHP_BZ2_UNINITIALIZED;

/* Note: We don't reinitialize here - it will be done on first use in the filter function */

return SUCCESS;
}

static void php_bz2_decompress_dtor(php_stream_filter *thisfilter)
{
if (thisfilter && Z_PTR(thisfilter->abstract)) {
Expand All @@ -193,6 +227,7 @@ static void php_bz2_decompress_dtor(php_stream_filter *thisfilter)

static const php_stream_filter_ops php_bz2_decompress_ops = {
php_bz2_decompress_filter,
php_bz2_decompress_seek,
php_bz2_decompress_dtor,
"bzip2.decompress"
};
Expand Down Expand Up @@ -288,6 +323,41 @@ static php_stream_filter_status_t php_bz2_compress_filter(
return exit_status;
}

static zend_result php_bz2_compress_seek(
php_stream *stream,
php_stream_filter *thisfilter,
zend_off_t offset,
int whence
)
{
int status;

if (!Z_PTR(thisfilter->abstract)) {
return FAILURE;
}

php_bz2_filter_data *data = Z_PTR(thisfilter->abstract);

/* End current compression */
BZ2_bzCompressEnd(&(data->strm));

/* Reset stream state */
data->strm.next_in = data->inbuf;
data->strm.avail_in = 0;
data->strm.next_out = data->outbuf;
data->strm.avail_out = data->outbuf_len;
data->is_flushed = 1;

/* Reinitialize compression with saved configuration */
status = BZ2_bzCompressInit(&(data->strm), data->blockSize100k, 0, data->workFactor);
if (status != BZ_OK) {
php_error_docref(NULL, E_WARNING, "bzip2.compress: failed to reset compression state");
return FAILURE;
}

return SUCCESS;
}

static void php_bz2_compress_dtor(php_stream_filter *thisfilter)
{
if (Z_PTR(thisfilter->abstract)) {
Expand All @@ -301,6 +371,7 @@ static void php_bz2_compress_dtor(php_stream_filter *thisfilter)

static const php_stream_filter_ops php_bz2_compress_ops = {
php_bz2_compress_filter,
php_bz2_compress_seek,
php_bz2_compress_dtor,
"bzip2.compress"
};
Expand All @@ -309,7 +380,7 @@ static const php_stream_filter_ops php_bz2_compress_ops = {

/* {{{ bzip2.* common factory */

static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *filterparams, uint8_t persistent)
static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *filterparams, bool persistent)
{
const php_stream_filter_ops *fops = NULL;
php_bz2_filter_data *data;
Expand Down Expand Up @@ -388,6 +459,10 @@ static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *fi
}
}

/* Save configuration for reset */
data->blockSize100k = blockSize100k;
data->workFactor = workFactor;

status = BZ2_bzCompressInit(&(data->strm), blockSize100k, 0, workFactor);
data->is_flushed = 1;
fops = &php_bz2_compress_ops;
Expand All @@ -403,7 +478,7 @@ static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *fi
return NULL;
}

return php_stream_filter_alloc(fops, data, persistent);
return php_stream_filter_alloc(fops, data, persistent, PSFS_SEEKABLE_START);
}

const php_stream_filter_factory php_bz2_filter_factory = {
Expand Down
55 changes: 55 additions & 0 deletions ext/bz2/tests/bz2_filter_seek_compress.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
--TEST--
bzip2.compress filter with seek to start
--EXTENSIONS--
bz2
--FILE--
<?php
$file = __DIR__ . '/bz2_filter_seek_compress.bz2';

$text1 = 'Short text.';
$text2 = 'This is a much longer text that will completely overwrite the previous compressed data in the file.';

$fp = fopen($file, 'w+');
stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE);

fwrite($fp, $text1);
fflush($fp);

$size1 = ftell($fp);
echo "Size after first write: $size1\n";

$result = fseek($fp, 0, SEEK_SET);
echo "Seek to start: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n";

fwrite($fp, $text2);
fflush($fp);

$size2 = ftell($fp);
echo "Size after second write: $size2\n";
echo "Second write is larger: " . ($size2 > $size1 ? "YES" : "NO") . "\n";

$result = fseek($fp, 50, SEEK_SET);
echo "Seek to middle: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n";

fclose($fp);

$fp = fopen($file, 'r');
stream_filter_append($fp, 'bzip2.decompress', STREAM_FILTER_READ);
$content = stream_get_contents($fp);
fclose($fp);

echo "Decompressed content matches text2: " . ($content === $text2 ? "YES" : "NO") . "\n";
?>
--CLEAN--
<?php
@unlink(__DIR__ . '/bz2_filter_seek_compress.bz2');
?>
--EXPECTF--
Size after first write: 40
Seek to start: SUCCESS
Size after second write: 98
Second write is larger: YES

Warning: fseek(): Stream filter bzip2.compress is seekable only to start position in %s on line %d
Seek to middle: FAILURE
Decompressed content matches text2: YES
43 changes: 43 additions & 0 deletions ext/bz2/tests/bz2_filter_seek_decompress.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
--TEST--
bzip2.decompress filter with seek to start
--EXTENSIONS--
bz2
--FILE--
<?php
$file = __DIR__ . '/bz2_filter_seek_decompress.bz2';

$text = 'I am the very model of a modern major general, I\'ve information vegetable, animal, and mineral.';

$fp = fopen($file, 'w');
stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE);
fwrite($fp, $text);
fclose($fp);

$fp = fopen($file, 'r');
stream_filter_append($fp, 'bzip2.decompress', STREAM_FILTER_READ);

$partial = fread($fp, 20);
echo "First read (20 bytes): " . $partial . "\n";

$result = fseek($fp, 0, SEEK_SET);
echo "Seek to start: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n";

$full = stream_get_contents($fp);
echo "Content after seek matches: " . ($full === $text ? "YES" : "NO") . "\n";

$result = fseek($fp, 50, SEEK_SET);
echo "Seek to middle: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n";

fclose($fp);
?>
--CLEAN--
<?php
@unlink(__DIR__ . '/bz2_filter_seek_decompress.bz2');
?>
--EXPECTF--
First read (20 bytes): I am the very model
Seek to start: SUCCESS
Content after seek matches: YES

Warning: fseek(): Stream filter bzip2.decompress is seekable only to start position in %s on line %d
Seek to middle: FAILURE
7 changes: 3 additions & 4 deletions ext/com_dotnet/com_dotnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ static HRESULT dotnet_bind_runtime(LPVOID FAR *ppv)
typedef HRESULT (STDAPICALLTYPE *cbtr_t)(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
cbtr_t CorBindToRuntime;
OLECHAR *oleversion;
char *version;

mscoree = LoadLibraryA("mscoree.dll");
if (mscoree == NULL) {
Expand All @@ -140,11 +139,11 @@ static HRESULT dotnet_bind_runtime(LPVOID FAR *ppv)
return S_FALSE;
}

version = INI_STR("com.dotnet_version");
if (version == NULL || *version == '\0') {
const zend_string *version = zend_ini_str_literal("com.dotnet_version");
if (version == NULL || ZSTR_LEN(version) == 0) {
oleversion = NULL;
} else {
oleversion = php_com_string_to_olestring(version, strlen(version), COMG(code_page));
oleversion = php_com_string_to_olestring(ZSTR_VAL(version), ZSTR_LEN(version), COMG(code_page));
}

hr = CorBindToRuntime(oleversion, NULL, &CLSID_CorRuntimeHost, &IID_ICorRuntimeHost, ppv);
Expand Down
Loading