php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #46814 Relative includes from symlinked directories fail
Submitted: 2008-12-09 18:17 UTC Modified: 2008-12-29 01:00 UTC
Votes:21
Avg. Score:4.3 ± 0.8
Reproduced:20 of 21 (95.2%)
Same Version:3 (15.0%)
Same OS:6 (30.0%)
From: dennis dot birkholz at nexxes dot net Assigned:
Status: No Feedback Package: Scripting Engine problem
PHP Version: 5.2.8 OS: Gentoo/Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: dennis dot birkholz at nexxes dot net
New email:
PHP Version: OS:

 

 [2008-12-09 18:17 UTC] dennis dot birkholz at nexxes dot net
Description:
------------
include statement seems to resolve the current working directory other than the rest of php so if I am in a symlinked directory an try to include a file using a relative path (containing ../), the include fails because the original path of the script is used to resolve the relative include and not the path the script is invoked from.

Reproduce code:
---------------
Asume the following files/directory structure:
Directory /test1
Directory /htdocs
Directory /htdocs/docs
Symlink /htdocs/test2 -> /test1
File /test1/index.php
File /htdocs/docs/docs.inc.php

DocumentRoot is /htdocs

File-Contents of /test1/index.php
<?php
  include("../docs/docs.inc.php");
//  ... other code
?>

Expected result:
----------------
No error, output generated by code after the include

Actual result:
--------------
An error: failed to open stream: No such file or directory
(/test1/index.php:2)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-12-17 22:35 UTC] dennis dot birkholz at nexxes dot net
This IS a bug: in Linux (and Unix like systems) beeing in a symlinked directory should behave exactly like beeing in a directory with the same content.

To use my example: If I use a shell and change to the folder /htdocs/test2 (which is a symlink to /test1), ls ../docs/docs.inc.php will show me the file "/htdocs/docs/docs.inc.php" and NOT "/docs/docs.inc.php".
 [2008-12-18 09:05 UTC] php at degoulet dot net
I don't realy understand your problem ?!
[root@pix sdv]# ls -alR
.:
total 16
drwxr-xr-x  4 root     root    4096 Dec 17 17:44 .
drwxrwxrwx  3 via      ftponly 4096 Dec 17 17:44 ..
drwxr-xr-x  2 root     root    4096 Dec 17 17:45 docs
drwxr-xr-x  2 root     root    4096 Dec 17 17:46 test1
lrwxrwxrwx  1 root     root       5 Dec 17 17:44 test2 -> test1

./docs:
total 12
drwxr-xr-x  2 root root 4096 Dec 17 17:45 .
drwxr-xr-x  4 root root 4096 Dec 17 17:44 ..
-rw-r--r--  1 root root   24 Dec 17 17:45 docs.inc.php

./test1:
total 12
drwxr-xr-x  2 root root 4096 Dec 17 17:46 .
drwxr-xr-x  4 root root 4096 Dec 17 17:44 ..
-rw-r--r--  1 root root   50 Dec 17 17:46 index.php

[root@pix sdv]# cat test1/index.php 
<?php
include("../docs/docs.inc.php");
echo "ok\n";
?>
[root@pix sdv]# cat docs/docs.inc.php 
<?php
echo "docs\n";
?>

No problem when i try this with apache :
http://www.xxxx.com/sdv/test1/index.php
http://www.xxxx.com/sdv/test2/index.php
==> same output : docs ok 

if you try this in command line.
3 cases :
- pwd= test1 : php index.php => output docs ok
- pwd= test2 : php index.php => output docs ok
- pwd= anywhere else : php ./test1/index.php : include(): Unable to access ../docs/docs.inc.php which is quite normal
the include path is relative to the current directory where php is executed not relative to the php script which is executed ...

isn't it ?
 [2008-12-18 21:28 UTC] dennis dot birkholz at nexxes dot net
No, you did not read my initial post correctly:
a file/directory starting with a / (like /test1) means it is in the root-directory. All example pathnames where absolute pathnames, not relative.

Here comes my listing for you:

/htdocs/:
total 12
drwxr-xr-x  3 root root 4096 Dec 18 22:23 ./
drwxr-xr-x 22 root root 4096 Dec 18 22:23 ../
drwxr-xr-x  2 root root 4096 Dec 18 22:23 docs/
lrwxrwxrwx  1 root root    6 Dec 18 22:23 test2 -> /test1/

/htdocs/docs/:
insgesamt 8
drwxr-xr-x 2 root root 4096 18. Dez 22:23 ./
drwxr-xr-x 3 root root 4096 18. Dez 22:23 ../
-rw-r--r-- 1 root root    0 18. Dez 22:23 docs.inc.php

/test1/:
total 8
drwxr-xr-x  2 root root 4096 18. Dez 22:24 ./
drwxr-xr-x 22 root root 4096 18. Dez 22:23 ../
-rw-r--r--  1 root root    0 18. Dez 22:24 index.php

Please note that test1 and test2 are not on the same directory level!
 [2008-12-21 13:12 UTC] jani@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


 [2008-12-29 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2009-09-03 14:24 UTC] michele dot manzato at gmail dot com
I confirm this bug. Here is the simplest reproduce code that I was able to make up:

~$ cd /tmp
/tmp$ mkdir a
/tmp$ mkdir b
/tmp$ echo '<?php echo getcwd(); require "../inc.php";?>' > a/test.php
/tmp$ echo '<?php echo "ok\n";?>' > b/inc.php
/tmp$ ln -s /tmp/a b/c
/tmp$ cd b/c/
/tmp/b/c$ php -f test.php
/tmp/a
Warning: require(../inc.php): failed to open stream: No such file or directory in /tmp/a/test.php on line 1

As one can see, the script's CWD is /tmp/a although the script was run from /tmp/b/c. As a result the following require() instruction fails because it can't find /inc.php (which should have been /tmp/b/inc.php instead).

The problem here is not the require(). It is that the CWD is converted to the real path when, instead, it should remain the symlinked path.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Nov 24 02:01:28 2024 UTC