Skip to content

Commit ea3c992

Browse files
committed
Fix #80960: opendir() warning wrong info when failed on Windows
Firstly, we must not forget to set appropriate error codes for "manual" checks in `virtual_file_ex()`. Secondly, we must not call `php_error_docref2()` for warnings regarding unary functions; thus, we introduce `php_win32_docref1_from_error()`. Closes GH-6872.
1 parent 0071c7e commit ea3c992

File tree

10 files changed

+58
-10
lines changed

10 files changed

+58
-10
lines changed

NEWS

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ PHP NEWS
33
?? ??? ????, PHP 7.4.19
44

55
- Core:
6-
. Fixed bug #80929 (Method name corruption related to repeated calls to call_user_func_array).
7-
(twosee)
6+
. Fixed bug #80929 (Method name corruption related to repeated calls to
7+
call_user_func_array). (twosee)
8+
. Fixed bug #80960 (opendir() warning wrong info when failed on Windows).
9+
(cmb)
810

911
- SPL:
1012
. Fixed bug #80933 (SplFileObject::DROP_NEW_LINE is broken for NUL and CR).

Zend/zend_virtual_cwd.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,11 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
10671067
}
10681068
#endif
10691069
if (path_length + state_cwd_length + 1 >= MAXPATHLEN-1) {
1070+
#ifdef ZEND_WIN32
1071+
SET_ERRNO_FROM_WIN32_CODE(ERROR_BUFFER_OVERFLOW);
1072+
#else
1073+
errno = ENAMETOOLONG;
1074+
#endif
10701075
return 1;
10711076
}
10721077
memcpy(resolved_path, state->cwd, state_cwd_length);
@@ -1095,6 +1100,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
10951100
#ifdef ZEND_WIN32
10961101
if (memchr(resolved_path, '*', path_length) ||
10971102
memchr(resolved_path, '?', path_length)) {
1103+
SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_NAME);
10981104
return 1;
10991105
}
11001106
#endif

ext/phar/tests/phar_buildfromdirectory2-win.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ __HALT_COMPILER();
2626
?>
2727
--EXPECTF--
2828
%s(24) "UnexpectedValueException"
29-
RecursiveDirectoryIterator::__construct(1,1): %s (code: 2)
29+
RecursiveDirectoryIterator::__construct(1): %s (code: 2)
3030
===DONE===

ext/phar/tests/phar_gobyebye-win32.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ bool(false)
4242
bool(false)
4343
bool(false)
4444

45-
Warning: opendir(foo/hi,foo/hi): %s (code: 3) in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d
45+
Warning: opendir(foo/hi): %s (code: 3) in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d
4646

4747
Warning: opendir(foo/hi): failed to open dir: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d
4848
===DONE===

ext/standard/tests/dir/bug80960.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Fix #80960 (opendir() warning wrong info when failed on Windows)
3+
--SKIPIF--
4+
<?php
5+
if (PHP_OS_FAMILY !== "Windows") die("skip for Windows only");
6+
?>
7+
--INI--
8+
log_errors_max_len=0
9+
--FILE--
10+
<?php
11+
opendir("notexist*");
12+
opendir("notexist?");
13+
opendir(str_pad("longname", PHP_MAXPATHLEN - strlen(getcwd()), "_"));
14+
?>
15+
--EXPECTF--
16+
Warning: opendir(notexist*): %s (code: 123) in %s on line %d
17+
18+
Warning: opendir(notexist*): failed to open dir: No such file or directory in %s on line %d
19+
20+
Warning: opendir(notexist?): %s (code: 123) in %s on line %d
21+
22+
Warning: opendir(notexist?): failed to open dir: No such file or directory in %s on line %d
23+
24+
Warning: opendir(longname%r_+%r): %s (code: 111) in %s on line %d
25+
26+
Warning: opendir(longname%r_+%r): failed to open dir: Filename too long in %s on line %d

ext/standard/tests/dir/opendir_variation6-win32.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,24 @@ rmdir($dir_path);
5151

5252
-- Wildcard = '*' --
5353

54-
Warning: opendir(%s/opendir_var*,%s/opendir_var*): %s in %s on line %d
54+
Warning: opendir(%s/opendir_var*): %s in %s on line %d
5555

5656
Warning: opendir(%s/opendir_var*): failed to open dir: %s in %s on line %d
5757
bool(false)
5858

59-
Warning: opendir(%s/*,%s/*): %s in %s on line %d
59+
Warning: opendir(%s/*): %s in %s on line %d
6060

6161
Warning: opendir(%s/*): failed to open dir: %s in %s on line %d
6262
bool(false)
6363

6464
-- Wildcard = '?' --
6565

66-
Warning: opendir(%s/opendir_variation6/sub_dir?,%s/opendir_variation6/sub_dir?): %s in %s on line %d
66+
Warning: opendir(%s/opendir_variation6/sub_dir?): %s in %s on line %d
6767

6868
Warning: opendir(%s/opendir_variation6/sub_dir?): failed to open dir: %s in %s on line %d
6969
bool(false)
7070

71-
Warning: opendir(%s/opendir_variation6/sub?dir1,%s/opendir_variation6/sub?dir1): %s in %s on line %d
71+
Warning: opendir(%s/opendir_variation6/sub?dir1): %s in %s on line %d
7272

7373
Warning: opendir(%s/opendir_variation6/sub?dir1): failed to open dir: %s in %s on line %d
7474
bool(false)

ext/standard/tests/general_functions/bug44295-win.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ try {
2525
<?php exit(0); ?>
2626
--EXPECTF--
2727
before
28-
in catch: DirectoryIterator::__construct(c:\not\exists\here,c:\not\exists\here): %s (code: 3)
28+
in catch: DirectoryIterator::__construct(c:\not\exists\here): %s (code: 3)
2929
==DONE==

main/main.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,19 @@ PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1,
11801180
/* }}} */
11811181

11821182
#ifdef PHP_WIN32
1183+
PHPAPI ZEND_COLD void php_win32_docref1_from_error(DWORD error, const char *param1) {
1184+
char *buf = php_win32_error_to_msg(error);
1185+
size_t buf_len;
1186+
1187+
buf_len = strlen(buf);
1188+
if (buf_len >= 2) {
1189+
buf[buf_len - 1] = '\0';
1190+
buf[buf_len - 2] = '\0';
1191+
}
1192+
php_error_docref1(NULL, param1, E_WARNING, "%s (code: %lu)", buf, error);
1193+
php_win32_error_msg_free(buf);
1194+
}
1195+
11831196
PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2) {
11841197
char *buf = php_win32_error_to_msg(error);
11851198
size_t buf_len;

main/php.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ PHPAPI ZEND_COLD void php_error_docref1(const char *docref, const char *param1,
346346
PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format, ...)
347347
PHP_ATTRIBUTE_FORMAT(printf, 5, 6);
348348
#ifdef PHP_WIN32
349+
PHPAPI ZEND_COLD void php_win32_docref1_from_error(DWORD error, const char *param1);
349350
PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2);
350351
#endif
351352
END_EXTERN_C()

main/streams/plain_wrapper.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, const
10181018

10191019
#ifdef PHP_WIN32
10201020
if (!dir) {
1021-
php_win32_docref2_from_error(GetLastError(), path, path);
1021+
php_win32_docref1_from_error(GetLastError(), path);
10221022
}
10231023

10241024
if (dir && dir->finished) {

0 commit comments

Comments
 (0)