Bug #79398 [Com]: Different behavior of flock and include on PHP 7.3 and PHP 7.4

From: Date: Sun, 04 Jul 2021 04:03:50 +0000
Subject: Bug #79398 [Com]: Different behavior of flock and include on PHP 7.3 and PHP 7.4
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-234791@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=79398&edit=1

 ID:                 79398
 Comment by:         dallas at ekkysoftware dot com
 Reported by:        praszywka dot adam at gmail dot com
 Summary:            Different behavior of flock and include on PHP 7.3
                     and PHP 7.4
 Status:             Not a bug
 Type:               Bug
 Package:            *General Issues
 Operating System:   Windows 10 1909
 PHP Version:        7.4.4
 Assigned To:        cmb
 Block user comment: N
 Private report:     N

 New Comment:

Just to follow that up, I have flock($file), then require($file). The flock is preventing the
require from reading the file, even though I am the same process.


Previous Comments:
------------------------------------------------------------------------
[2021-07-04 03:01:53] dallas at ekkysoftware dot com

This is a bug. Everything works in PHP7.3, but this issue shows up in PHP7.4.

require(): read of 25405 bytes failed with errno=13 Permission denied

On Windows there are no OS permissions to block the read, and in any case a permissions issue should
block the file open and not the file read. Also the '25405' is the correct filesize for
the included file, which shows the system can get stat the file, the path is correct and with
readable permissions.

------------------------------------------------------------------------
[2020-03-22 17:02:35] cmb@php.net

Okay, better reproducer:

<?php
$lock = fopen($cachePath, 'w');
fwrite($lock, '<?php echo "test\n";');
flock($lock, LOCK_EX);
include $cachePath;
?>

Anyhow, the behavioral change has been triggered by lexing no
longer using mmap()[1]; however, the new behavior is now in line
with other file functions, e.g.

<?php
$lock = fopen($cachePath, 'w');
fwrite($lock, '<?php echo "test\n";');
flock($lock, LOCK_EX);
echo file_get_contents($cachePath);
?>

On Windows, this produces no output (PHP 7.3 and 7.4).  On Linux,
this usually prints the contents of the file.  The relevant
difference is that flock() uses advisory locking on Linux by
default, while it is always mandatory on Windows.

So a reasonable fix for Symfony would be using a separate lock file,
like suggested by Nicolas[2].

[1] <http://git.php.net/?p=php-src.git;a=commit;h=5161cebe28cca36fa7f7989b5a799290a3f1eb6a>
[2] <https://github.com/symfony/symfony/issues/36132#issuecomment-601708409>

------------------------------------------------------------------------
[2020-03-21 21:34:19] praszywka dot adam at gmail dot com

That's the way how Symfony is currently creating cache.

Topic was stared here: https://github.com/symfony/symfony/issues/36132

It's not a standard way of using flock and include so I reported it as a incompatibility
between PHP < 7.{0,1,2,3} and 7.4.

That problem should be fixed in Symfony or PHP - it should be decided where.

------------------------------------------------------------------------
[2020-03-21 15:20:48] cmb@php.net

> PHP 7.3 allows to include previously locked file.

I'm confused, since opening the file in 'w' mode immediately
truncates it.  Why would you include an empty file in the first
place?

------------------------------------------------------------------------
[2020-03-20 13:59:06] praszywka dot adam at gmail dot com

Description:
------------
PHP 7.3 allows to include previously locked file. PHP 7.4 throws Notice.

Test script:
---------------
<?php

$cachePath = 'file.php';

$lock = fopen($cachePath, 'w');
chmod($cachePath, 0666 & ~umask());

$res = flock($lock, LOCK_EX | LOCK_NB, $wouldBlock);

include $cachePath;

echo 'OK';


Expected result:
----------------
$ C:/Program\ Files/php-7.3.5-nts-Win32-VC15-x64/php.exe test2.php
OK


Actual result:
--------------
$ C:/Program\ Files/php-7.4.4-nts-Win32-VC15-x64/php.exe test2.php
PHP Notice:  include(): read of 4096 bytes failed with errno=13 Permission denied in
C:\Users\praszywa\Downloads\test\test2.php on line 10
PHP Stack trace:
PHP   1. {main}() C:\Users\praszywa\Downloads\test\test2.php:0

Notice: include(): read of 4096 bytes failed with errno=13 Permission denied in
C:\Users\praszywa\Downloads\test\test2.php on line 10

Call Stack:
    0.0002     393720   1. {main}() C:\Users\praszywa\Downloads\test\test2.php:0

PHP Warning:  include(): Failed opening 'file.php' for inclusion
(include_path='.;C:\php\pear') in C:\Users\praszywa\Downloads\test\test2.php on line 10
PHP Stack trace:
PHP   1. {main}() C:\Users\praszywa\Downloads\test\test2.php:0

Warning: include(): Failed opening 'file.php' for inclusion
(include_path='.;C:\php\pear') in C:\Users\praszywa\Downloads\test\test2.php on line 10

Call Stack:
    0.0002     393720   1. {main}() C:\Users\praszywa\Downloads\test\test2.php:0

OK


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=79398&edit=1


Thread (8 messages)

« previous php.bugs (#234791) next »