Skip to content

Commit 9ed83e1

Browse files
committed
Merge branch 'PHP-8.4'
2 parents de018aa + ed00c1d commit 9ed83e1

File tree

6 files changed

+154
-4
lines changed

6 files changed

+154
-4
lines changed

ext/standard/filestat.c

+12
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */
388388
php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
389389
RETURN_FALSE;
390390
}
391+
392+
php_clear_stat_cache(0, NULL, 0);
393+
391394
RETURN_TRUE;
392395
#endif
393396
}
@@ -527,6 +530,9 @@ static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */
527530
php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
528531
RETURN_FALSE;
529532
}
533+
534+
php_clear_stat_cache(0, NULL, 0);
535+
530536
RETURN_TRUE;
531537
#endif
532538
}
@@ -591,6 +597,9 @@ PHP_FUNCTION(chmod)
591597
php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
592598
RETURN_FALSE;
593599
}
600+
601+
php_clear_stat_cache(0, NULL, 0);
602+
594603
RETURN_TRUE;
595604
}
596605
/* }}} */
@@ -676,6 +685,9 @@ PHP_FUNCTION(touch)
676685
php_error_docref(NULL, E_WARNING, "Utime failed: %s", strerror(errno));
677686
RETURN_FALSE;
678687
}
688+
689+
php_clear_stat_cache(0, NULL, 0);
690+
679691
RETURN_TRUE;
680692
}
681693
/* }}} */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Bug #72666 (stat cache clearing inconsistent - touch)
3+
--FILE--
4+
<?php
5+
$filename = __DIR__ . '/bug72666_variation1.txt';
6+
7+
touch($filename);
8+
var_dump(filemtime($filename) > 2);
9+
touch($filename, 1);
10+
var_dump(filemtime($filename));
11+
12+
?>
13+
--CLEAN--
14+
<?php
15+
unlink(__DIR__ . '/bug72666_variation1.txt');
16+
?>
17+
--EXPECT--
18+
bool(true)
19+
int(1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
Bug #72666 (stat cache clearing inconsistent - chgrp, chmod)
3+
--SKIPIF--
4+
<?php
5+
if (substr(PHP_OS, 0, 3) == 'WIN') die('skip no windows support');
6+
if (!function_exists("posix_getgid")) die("skip no posix_getgid()");
7+
?>
8+
--FILE--
9+
<?php
10+
$filename = __DIR__ . '/bug72666_variation2.txt';
11+
12+
$gid = posix_getgid();
13+
14+
var_dump(touch($filename));
15+
$ctime1 = filectime($filename);
16+
sleep(1);
17+
var_dump(chgrp($filename,$gid));
18+
$ctime2 = filectime($filename);
19+
sleep(1);
20+
var_dump(chmod($filename, 0777));
21+
$ctime3 = filectime($filename);
22+
23+
var_dump($ctime2 > $ctime1);
24+
var_dump($ctime3 > $ctime2);
25+
?>
26+
--CLEAN--
27+
<?php
28+
unlink(__DIR__ . '/bug72666_variation2.txt');
29+
?>
30+
--EXPECT--
31+
bool(true)
32+
bool(true)
33+
bool(true)
34+
bool(true)
35+
bool(true)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
Bug #72666 (stat cache clearing inconsistent - plain wrapper)
3+
--FILE--
4+
<?php
5+
$filename = __DIR__ . '/bug72666_variation3.txt';
6+
7+
file_put_contents($filename, "test");
8+
$fd = fopen($filename, "r");
9+
$atime1 = fileatime($filename);
10+
sleep(1);
11+
var_dump(fread($fd, 4));
12+
$atime2 = fileatime($filename);
13+
$mtime1 = filemtime($filename);
14+
fclose($fd);
15+
$fd = fopen($filename, "w");
16+
sleep(1);
17+
var_dump(fwrite($fd, "data"));
18+
$mtime2 = filemtime($filename);
19+
if (substr(PHP_OS, 0, 3) == 'WIN') {
20+
// Windows do not hundle atime
21+
var_dump($atime2 == $atime1);
22+
} else {
23+
var_dump($atime2 > $atime1);
24+
}
25+
var_dump($mtime2 > $mtime1);
26+
?>
27+
--CLEAN--
28+
<?php
29+
unlink(__DIR__ . '/bug72666_variation3.txt');
30+
?>
31+
--EXPECT--
32+
string(4) "test"
33+
int(4)
34+
bool(true)
35+
bool(true)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Bug #72666 (stat cache clearing inconsistent - exec)
3+
--FILE--
4+
<?php
5+
$filename = __DIR__ . '/bug72666_variation4.txt';
6+
7+
touch($filename, 1);
8+
var_dump(filemtime($filename));
9+
exec("touch $filename");
10+
var_dump(filemtime($filename) > 1);
11+
12+
13+
touch($filename, 1);
14+
var_dump(filemtime($filename));
15+
shell_exec("touch $filename");
16+
var_dump(filemtime($filename) > 1);
17+
?>
18+
--CLEAN--
19+
<?php
20+
unlink(__DIR__ . '/bug72666_variation4.txt');
21+
?>
22+
--EXPECT--
23+
int(1)
24+
bool(true)
25+
int(1)
26+
bool(true)

main/streams/plain_wrapper.c

+27-4
Original file line numberDiff line numberDiff line change
@@ -349,14 +349,15 @@ PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STRE
349349
static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t count)
350350
{
351351
php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract;
352+
ssize_t bytes_written;
352353

353354
assert(data != NULL);
354355

355356
if (data->fd >= 0) {
356357
#ifdef PHP_WIN32
357-
ssize_t bytes_written = _write(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count));
358+
bytes_written = _write(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count));
358359
#else
359-
ssize_t bytes_written = write(data->fd, buf, count);
360+
bytes_written = write(data->fd, buf, count);
360361
#endif
361362
if (bytes_written < 0) {
362363
if (PHP_IS_TRANSIENT_ERROR(errno)) {
@@ -370,7 +371,6 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun
370371
php_error_docref(NULL, E_NOTICE, "Write of %zu bytes failed with errno=%d %s", count, errno, strerror(errno));
371372
}
372373
}
373-
return bytes_written;
374374
} else {
375375

376376
#ifdef HAVE_FLUSHIO
@@ -380,8 +380,15 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun
380380
data->last_op = 'w';
381381
#endif
382382

383-
return (ssize_t) fwrite(buf, 1, count, data->file);
383+
bytes_written = (ssize_t) fwrite(buf, 1, count, data->file);
384384
}
385+
386+
if (EG(active)) {
387+
/* clear stat cache as mtime and ctime got changed */
388+
php_clear_stat_cache(0, NULL, 0);
389+
}
390+
391+
return bytes_written;
385392
}
386393

387394
static ssize_t php_stdiop_read(php_stream *stream, char *buf, size_t count)
@@ -460,6 +467,12 @@ static ssize_t php_stdiop_read(php_stream *stream, char *buf, size_t count)
460467

461468
stream->eof = feof(data->file);
462469
}
470+
471+
if (EG(active)) {
472+
/* clear stat cache as atime got changed */
473+
php_clear_stat_cache(0, NULL, 0);
474+
}
475+
463476
return ret;
464477
}
465478

@@ -540,6 +553,10 @@ static int php_stdiop_flush(php_stream *stream)
540553
* something completely different.
541554
*/
542555
if (data->file) {
556+
if (EG(active)) {
557+
/* clear stat cache as there might be a write so mtime and ctime might have changed */
558+
php_clear_stat_cache(0, NULL, 0);
559+
}
543560
return fflush(data->file);
544561
}
545562
return 0;
@@ -1159,6 +1176,12 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, zen
11591176
ret = php_stream_fopen_from_fd_rel(fd, mode, persistent_id, (open_flags & O_APPEND) == 0);
11601177
}
11611178

1179+
if (EG(active)) {
1180+
/* clear stat cache as mtime and ctime might got changed - phar can use stream before
1181+
* cache is initialized so we need to check if the execution is active. */
1182+
php_clear_stat_cache(0, NULL, 0);
1183+
}
1184+
11621185
if (ret) {
11631186
if (opened_path) {
11641187
*opened_path = zend_string_init(realpath, strlen(realpath), 0);

0 commit comments

Comments
 (0)