Hey Dmitry, could you take a look at this one. I think this is mostly
your code and I am a bit lost in the path manipulation that is going on
here. This is bug https://bugs.php.net/51860 and it can be reproduced
from cli like this:
% cd /
% ln -s / phptest
% echo "OK" > /phpfile
% echo '<?php include "/phptest/phpfile";' > /phpinc
% php /phptest/phpinc
And you will see that it can't find /phptest/phpfile
But magically if you run it like this:
% php phptest/phpinc
it works fine.
The problem is that /phptest gets cached without the directory bit set.
And when we read it back from the cache and see it isn't a directory we
obviously don't think it can contain a file. It works in the second case
because of what is probably a secondary bug and that is that it ends up
caching //phptest instead of /phptest. So in that case there is a cache
miss on the include and it doesn't fail. However, if you add a second
include that includes another file from /phptest then the first include
would have caused /phptest to get cached and the second include will
then fail.
If you do this exact same test from /foo instead of from / then
/foo/phptest which in this case is a symlink to /foo correctly gets
cached with directory=1.
So somewhere in the while(1) loop logic in tsrm_realpath_r() we fail to
get to the point where we stat / and set the directory bit.
Obviously if someone else wants to fire up gdb to find the likely
off-by-one error that is causing this, please do.
-Rasmus
Hi Rasmus,
I've reproduced it and will take a deeper look a bit later today.
Thanks. Dmitry.
Hey Dmitry, could you take a look at this one. I think this is mostly
your code and I am a bit lost in the path manipulation that is going on
here. This is bug https://bugs.php.net/51860 and it can be reproduced
from cli like this:% cd /
% ln -s / phptest
% echo "OK"> /phpfile
% echo '<?php include "/phptest/phpfile";'> /phpinc% php /phptest/phpinc
And you will see that it can't find /phptest/phpfile
But magically if you run it like this:
% php phptest/phpinc
it works fine.
The problem is that /phptest gets cached without the directory bit set.
And when we read it back from the cache and see it isn't a directory we
obviously don't think it can contain a file. It works in the second case
because of what is probably a secondary bug and that is that it ends up
caching //phptest instead of /phptest. So in that case there is a cache
miss on the include and it doesn't fail. However, if you add a second
include that includes another file from /phptest then the first include
would have caused /phptest to get cached and the second include will
then fail.If you do this exact same test from /foo instead of from / then
/foo/phptest which in this case is a symlink to /foo correctly gets
cached with directory=1.So somewhere in the while(1) loop logic in tsrm_realpath_r() we fail to
get to the point where we stat / and set the directory bit.Obviously if someone else wants to fire up gdb to find the likely
off-by-one error that is causing this, please do.-Rasmus