Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
95b4710
stream: add initial stream errors API
bukka Sep 30, 2025
435338d
stream: add error codes and handler check
bukka Nov 16, 2025
2f8a84e
stream: convert phar errors
bukka Nov 16, 2025
4f56e7e
stream: convert ftp wrapper errors
bukka Nov 16, 2025
5979d7e
stream: add few more errors to replace generic errors in phar and ftp
bukka Nov 16, 2025
1767a7d
stream: convert http wrapper errors
bukka Nov 16, 2025
d5e246c
stream: add context param to php_stream_wrapper_log_* variants
bukka Nov 16, 2025
1b00f7e
stream: convert php fopen wrapper
bukka Nov 16, 2025
ff51dec
stream: convert memory wrappers errors
bukka Nov 16, 2025
13b256f
stream: convert plain wrappers errors
bukka Nov 16, 2025
0e3c995
stream: convert cast errors
bukka Nov 16, 2025
703e8c8
stream: convert filter errors
bukka Nov 16, 2025
dc8d38b
stream: convert core streams errors
bukka Nov 16, 2025
c906551
stream: add docref param to error functions
bukka Nov 17, 2025
cf9685f
stream: convert transport errors
bukka Nov 17, 2025
0426e30
stream: store wrapper erros by name instead of ptr
bukka Nov 17, 2025
6f730f8
stream: convert user stream wrapper errors
bukka Nov 17, 2025
c21470d
stream: convert xp_socket errors
bukka Nov 17, 2025
2652ff7
stream: fix compilation issues in core stream errors
bukka Nov 17, 2025
2ced095
stream: extend and fix php_stream_display_wrapper_errors
bukka Nov 17, 2025
ea1b31c
stream: fix phar errors
bukka Nov 17, 2025
8aa958f
stream: fix http wrapper errors
bukka Nov 17, 2025
a50519e
stream: fix user wrapper error calls
bukka Nov 17, 2025
db3f377
stream: fix php_stream_display_wrapper_errors usage
bukka Nov 17, 2025
3cd9b6d
stream: fix wrapper selection for displaying logged errors
bukka Nov 17, 2025
03902be
stream: fix wrapper key in php_stream_tidy_wrapper_error_log
bukka Nov 18, 2025
e2555ab
stream: stream remove not reported warning
bukka Nov 18, 2025
18d55d6
stream: fix reporting errors in rename
bukka Nov 18, 2025
937941d
stream: do not store wrapper errors if no REPORT_ERRORS set
bukka Nov 18, 2025
af6a536
stream: add stream_get_errors function
bukka Nov 18, 2025
e88385a
stream: fix error storing for persistent streams
bukka Nov 18, 2025
68a33bd
stream: add missing error mode and store constants
bukka Nov 18, 2025
91974e5
stream: set context for opened streams
bukka Nov 18, 2025
46f9993
stream: fix leaked stream error list
bukka Nov 18, 2025
1db1ab4
stream: add tests for new stream error handling
bukka Nov 18, 2025
a05924e
stream: update reflection class name test
bukka Nov 18, 2025
63b7b57
stream: fix possible use of wrapper after it is freed
bukka Nov 19, 2025
5a53a98
stream: fix double error message creation
bukka Nov 19, 2025
9b3a5d6
stream: fix empty wrapper check in error displaying
bukka Nov 19, 2025
0ec44f1
stream: generate optimizer info for stream_get_errors
bukka Nov 19, 2025
26d3a8a
stream: make exception wrapper optional
bukka Nov 19, 2025
b94fd18
stream: restructure error api
bukka Dec 28, 2025
c8784a8
stream: clean up and optimize wrapper errors
bukka Dec 28, 2025
3169e80
stream: fix test names
bukka Dec 28, 2025
98bd9f7
stream: fix docref initialization for stream errors
bukka Dec 28, 2025
84d370c
stream: optimize error operation handling
bukka Dec 28, 2025
dbfbcae
stream: modify error begin and end api
bukka Dec 28, 2025
bad3b38
stream: add error begin and end to standard/file.c
bukka Dec 28, 2025
cfc1d68
stream: fix and refactore errors operation parent handling
bukka Dec 29, 2025
39717a8
stream: fix incorrect stream error tests
bukka Dec 29, 2025
dc72566
stream: add error begin and end to standard/streamsfuncs.c
bukka Dec 29, 2025
ccd3f51
stream: use default context in errors if no context set
bukka Dec 29, 2025
a404f63
stream: remove php_stream_error_operation_free
bukka Dec 29, 2025
65a6c68
stream: fix stored errors copying
bukka Dec 29, 2025
540d000
stream: fix mix modes storage error test
bukka Dec 29, 2025
2739122
stream: remove chaining tests (already tested by mixed store)
bukka Dec 29, 2025
b960b77
stream: update reflection class names test
bukka Dec 29, 2025
397473f
stream: rename terminal errors to terminating
bukka Dec 29, 2025
1cf9820
stream: fix segfault with incompletely zeroed entry in dtor
bukka Dec 29, 2025
1d5f245
stream: re-order some errors and fix test
bukka Dec 29, 2025
d3c613c
stream: update optimizer info for stream_get_last_error
bukka Dec 29, 2025
ba08822
stream: use StreamError class constants for codes
bukka Feb 27, 2026
95ac95a
stream: prohibit setting error mode in default context
bukka Feb 27, 2026
60180b7
Revert "stream: use StreamError class constants for codes"
bukka Mar 29, 2026
b5d3c8f
stream: use error code non backed enums with c headers
bukka Mar 29, 2026
7822680
stream: return array of errors instead of linked list
bukka Mar 29, 2026
8dce66c
stream: fix optimizer info for stream_last_errors
bukka Mar 29, 2026
b033def
stream: fix errors function types
bukka Mar 29, 2026
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
1 change: 1 addition & 0 deletions Zend/Optimizer/zend_func_infos.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@ static const func_info_t func_infos[] = {
F1("stream_get_line", MAY_BE_STRING|MAY_BE_FALSE),
F1("stream_resolve_include_path", MAY_BE_STRING|MAY_BE_FALSE),
F1("stream_get_wrappers", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("stream_last_errors", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_OBJECT),
F1("stream_get_transports", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
#if defined(HAVE_GETTIMEOFDAY)
F1("uniqid", MAY_BE_STRING),
Expand Down
38 changes: 31 additions & 7 deletions build/gen_stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -3378,6 +3378,7 @@ class ClassInfo {
public array $funcInfos;
/** @var EnumCaseInfo[] */
private readonly array $enumCaseInfos;
private readonly bool $generateCNameTable;
public readonly ?string $cond;
public ?int $phpVersionIdMinimumCompatibility;
public readonly bool $isUndocumentable;
Expand Down Expand Up @@ -3408,6 +3409,7 @@ public function __construct(
array $propertyInfos,
array $funcInfos,
array $enumCaseInfos,
bool $generateCNameTable,
?string $cond,
?int $minimumPhpVersionIdCompatibility,
bool $isUndocumentable
Expand All @@ -3428,6 +3430,7 @@ public function __construct(
$this->propertyInfos = $propertyInfos;
$this->funcInfos = $funcInfos;
$this->enumCaseInfos = $enumCaseInfos;
$this->generateCNameTable = $generateCNameTable;
$this->cond = $cond;
$this->phpVersionIdMinimumCompatibility = $minimumPhpVersionIdCompatibility;
$this->isUndocumentable = $isUndocumentable;
Expand Down Expand Up @@ -3622,30 +3625,49 @@ public function getCDeclarations(): string
if ($this->type !== "enum") {
return '';
}

$code = '';

if ($this->cond) {
$code .= "#if {$this->cond}\n";
}

$cEnumName = 'zend_enum_' . str_replace('\\', '_', $this->name->toString());

$code .= "typedef enum {$cEnumName} {\n";

$i = 1;
foreach ($this->enumCaseInfos as $case) {
$cName = 'ZEND_ENUM_' . str_replace('\\', '_', $this->name->toString()) . '_' . $case->name;
$code .= "\t{$cName} = {$i},\n";
$i++;
}

$code .= "} {$cEnumName};\n";

$caseCount = count($this->enumCaseInfos);

if ($this->generateCNameTable && $caseCount > 0) {
$cPrefix = 'ZEND_ENUM_' . str_replace('\\', '_', $this->name->toString());
$useGuard = $cPrefix . '_USE_NAME_TABLE';

$code .= "\n#define {$cPrefix}_CASE_COUNT {$caseCount}\n";
$code .= "\n#ifdef {$useGuard}\n";
$code .= "static const char *{$cEnumName}_case_names[{$cPrefix}_CASE_COUNT + 1] = {\n";

foreach ($this->enumCaseInfos as $case) {
$cName = $cPrefix . '_' . $case->name;
$code .= "\t[{$cName}] = \"{$case->name}\",\n";
}

$code .= "};\n";
$code .= "#endif\n";
}

if ($this->cond) {
$code .= "#endif\n";
}

return $code;
}

Expand Down Expand Up @@ -5183,6 +5205,7 @@ function parseClass(
$isStrictProperties = array_key_exists('strict-properties', $tagMap);
$isNotSerializable = array_key_exists('not-serializable', $tagMap);
$isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
$generateCNameTable = array_key_exists('c-name-table', $tagMap);
foreach ($tags as $tag) {
if ($tag->name === 'alias') {
$alias = $tag->getValue();
Expand Down Expand Up @@ -5244,6 +5267,7 @@ function parseClass(
$properties,
$methods,
$enumCases,
$generateCNameTable,
$cond,
$minimumPhpVersionIdCompatibility,
$isUndocumentable
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1689,6 +1689,7 @@ PHP_ADD_SOURCES([main/streams], m4_normalize([
memory.c
mmap.c
plain_wrapper.c
stream_errors.c
streams.c
transports.c
userspace.c
Expand Down
98 changes: 68 additions & 30 deletions ext/phar/dirstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,37 +253,43 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path,
char *error;
phar_archive_data *phar;

if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) {
php_stream_wrapper_log_error(wrapper, options, "phar url \"%s\" is unknown", path);
if ((resource = phar_parse_url(wrapper, context, path, mode, options)) == NULL) {
php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl,
"phar url \"%s\" is unknown", path);
return NULL;
}

/* we must have at the very least phar://alias.phar/ */
if (!resource->scheme || !resource->host || !resource->path) {
if (resource->host && !resource->path) {
php_stream_wrapper_log_error(wrapper, options, "phar error: no directory in \"%s\", must have at least phar://%s/ for root directory (always use full path to a new phar)", path, ZSTR_VAL(resource->host));
php_stream_wrapper_log_warn(wrapper, context, options, InvalidPath,
"phar error: no directory in \"%s\", must have at least phar://%s/ for root directory (always use full path to a new phar)",
path, ZSTR_VAL(resource->host));
php_url_free(resource);
return NULL;
}
php_url_free(resource);
php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url \"%s\", must have at least phar://%s/", path, path);
php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl,
"phar error: invalid url \"%s\", must have at least phar://%s/", path, path);
return NULL;
}

if (!zend_string_equals_literal_ci(resource->scheme, "phar")) {
php_url_free(resource);
php_stream_wrapper_log_error(wrapper, options, "phar error: not a phar url \"%s\"", path);
php_stream_wrapper_log_warn(wrapper, context, options, ProtocolUnsupported,
"phar error: not a phar url \"%s\"", path);
return NULL;
}

phar_request_initialize();

if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) {
if (error) {
php_stream_wrapper_log_error(wrapper, options, "%s", error);
php_stream_wrapper_log_warn(wrapper, context, options, NotFound, "%s", error);
efree(error);
} else {
php_stream_wrapper_log_error(wrapper, options, "phar file \"%s\" is unknown", ZSTR_VAL(resource->host));
php_stream_wrapper_log_warn(wrapper, context, options, NotFound,
"phar file \"%s\" is unknown", ZSTR_VAL(resource->host));
}
php_url_free(resource);
return NULL;
Expand Down Expand Up @@ -353,7 +359,8 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo

/* pre-readonly check, we need to know if this is a data phar */
if (FAILURE == phar_split_fname(url_from, strlen(url_from), &arch, &arch_len, NULL, NULL, 2, 2)) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\", no phar archive specified", url_from);
php_stream_wrapper_log_warn(wrapper, context, options, NotFound,
"phar error: cannot create directory \"%s\", no phar archive specified", url_from);
return 0;
}

Expand All @@ -364,29 +371,34 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo
efree(arch);

if (PHAR_G(readonly) && (!phar || !phar->is_data)) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\", write operations disabled", url_from);
php_stream_wrapper_log_warn(wrapper, context, options, Readonly,
"phar error: cannot create directory \"%s\", write operations disabled", url_from);
return 0;
}

if ((resource = phar_parse_url(wrapper, url_from, "w", options)) == NULL) {
if ((resource = phar_parse_url(wrapper, context, url_from, "w", options)) == NULL) {
return 0;
}

/* we must have at the very least phar://alias.phar/internalfile.php */
if (!resource->scheme || !resource->host || !resource->path) {
php_url_free(resource);
php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url \"%s\"", url_from);
php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl,
"phar error: invalid url \"%s\"", url_from);
return 0;
}

if (!zend_string_equals_literal_ci(resource->scheme, "phar")) {
php_url_free(resource);
php_stream_wrapper_log_error(wrapper, options, "phar error: not a phar stream url \"%s\"", url_from);
php_stream_wrapper_log_warn(wrapper, context, options, ProtocolUnsupported,
"phar error: not a phar stream url \"%s\"", url_from);
return 0;
}

if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path) + 1, ZSTR_VAL(resource->host), error);
php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed,
"phar error: cannot create directory \"%s\" in phar \"%s\", error retrieving phar information: %s",
ZSTR_VAL(resource->path) + 1, ZSTR_VAL(resource->host), error);
efree(error);
php_url_free(resource);
return 0;
Expand All @@ -398,27 +410,35 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo
zend_string_efree(e->filename);
efree(e);
}
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", directory already exists", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host));
php_stream_wrapper_log_warn(wrapper, context, options, AlreadyExists,
"phar error: cannot create directory \"%s\" in phar \"%s\", directory already exists",
ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host));
php_url_free(resource);
return 0;
}

if (error) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error);
php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed,
"phar error: cannot create directory \"%s\" in phar \"%s\", %s",
ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error);
efree(error);
php_url_free(resource);
return 0;
}

if (phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1, 0, &error, true)) {
/* entry exists as a file */
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", file already exists", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host));
php_stream_wrapper_log_warn(wrapper, context, options, AlreadyExists,
"phar error: cannot create directory \"%s\" in phar \"%s\", file already exists",
ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host));
php_url_free(resource);
return 0;
}

if (error) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error);
php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed,
"phar error: cannot create directory \"%s\" in phar \"%s\", %s",
ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error);
efree(error);
php_url_free(resource);
return 0;
Expand Down Expand Up @@ -447,15 +467,19 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo
entry.old_flags = PHAR_ENT_PERM_DEF_DIR;

if (NULL == zend_hash_add_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info))) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", adding to manifest failed", ZSTR_VAL(entry.filename), phar->fname);
php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed,
"phar error: cannot create directory \"%s\" in phar \"%s\", adding to manifest failed",
ZSTR_VAL(entry.filename), phar->fname);
zend_string_efree(entry.filename);
return 0;
}

phar_flush(phar, &error);

if (error) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(entry.filename), phar->fname, error);
php_stream_wrapper_log_warn(wrapper, context, options, MkdirFailed,
"phar error: cannot create directory \"%s\" in phar \"%s\", %s",
ZSTR_VAL(entry.filename), phar->fname, error);
zend_hash_del(&phar->manifest, entry.filename);
efree(error);
return 0;
Expand All @@ -479,7 +503,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options

/* pre-readonly check, we need to know if this is a data phar */
if (FAILURE == phar_split_fname(url, strlen(url), &arch, &arch_len, NULL, NULL, 2, 2)) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\", no phar archive specified, or phar archive does not exist", url);
php_stream_wrapper_log_warn(wrapper, context, options, NotFound,
"phar error: cannot remove directory \"%s\", no phar archive specified, or phar archive does not exist", url);
return 0;
}

Expand All @@ -490,29 +515,34 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
efree(arch);

if (PHAR_G(readonly) && (!phar || !phar->is_data)) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot rmdir directory \"%s\", write operations disabled", url);
php_stream_wrapper_log_warn(wrapper, context, options, Readonly,
"phar error: cannot rmdir directory \"%s\", write operations disabled", url);
return 0;
}

if ((resource = phar_parse_url(wrapper, url, "w", options)) == NULL) {
if ((resource = phar_parse_url(wrapper, context, url, "w", options)) == NULL) {
return 0;
}

/* we must have at the very least phar://alias.phar/internalfile.php */
if (!resource->scheme || !resource->host || !resource->path) {
php_url_free(resource);
php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url \"%s\"", url);
php_stream_wrapper_log_warn(wrapper, context, options, InvalidUrl,
"phar error: invalid url \"%s\"", url);
return 0;
}

if (!zend_string_equals_literal_ci(resource->scheme, "phar")) {
php_url_free(resource);
php_stream_wrapper_log_error(wrapper, options, "phar error: not a phar stream url \"%s\"", url);
php_stream_wrapper_log_warn(wrapper, context, options, ProtocolUnsupported,
"phar error: not a phar stream url \"%s\"", url);
return 0;
}

if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error);
php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed,
"phar error: cannot remove directory \"%s\" in phar \"%s\", error retrieving phar information: %s",
ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error);
efree(error);
php_url_free(resource);
return 0;
Expand All @@ -522,10 +552,14 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options

if (!(entry = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, path_len, 2, &error, true))) {
if (error) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error);
php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed,
"phar error: cannot remove directory \"%s\" in phar \"%s\", %s",
ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error);
efree(error);
} else {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", directory does not exist", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host));
php_stream_wrapper_log_warn(wrapper, context, options, NotFound,
"phar error: cannot remove directory \"%s\" in phar \"%s\", directory does not exist",
ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host));
}
php_url_free(resource);
return 0;
Expand All @@ -539,7 +573,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
zend_string_starts_with_cstr(str_key, ZSTR_VAL(resource->path)+1, path_len)
&& IS_SLASH(ZSTR_VAL(str_key)[path_len])
) {
php_stream_wrapper_log_error(wrapper, options, "phar error: Directory not empty");
php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed,
"phar error: Directory not empty");
if (entry->is_temp_dir) {
zend_string_efree(entry->filename);
efree(entry);
Expand All @@ -555,7 +590,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
zend_string_starts_with_cstr(str_key, ZSTR_VAL(resource->path)+1, path_len)
&& IS_SLASH(ZSTR_VAL(str_key)[path_len])
) {
php_stream_wrapper_log_error(wrapper, options, "phar error: Directory not empty");
php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed,
"phar error: Directory not empty");
if (entry->is_temp_dir) {
zend_string_efree(entry->filename);
efree(entry);
Expand All @@ -576,7 +612,9 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
phar_flush(phar, &error);

if (error) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(entry->filename), phar->fname, error);
php_stream_wrapper_log_warn(wrapper, context, options, RmdirFailed,
"phar error: cannot remove directory \"%s\" in phar \"%s\", %s",
ZSTR_VAL(entry->filename), phar->fname, error);
php_url_free(resource);
efree(error);
return 0;
Expand Down
2 changes: 1 addition & 1 deletion ext/phar/dirstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
#ifdef PHAR_DIRSTREAM
#include "ext/standard/url.h"

php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options);
php_url* phar_parse_url(php_stream_wrapper *wrapper, php_stream_context *context, const char *filename, const char *mode, int options);

/* directory handlers */
static ssize_t phar_dir_write(php_stream *stream, const char *buf, size_t count);
Expand Down
Loading
Loading