]> granicus.if.org Git - php/commitdiff
MFH: Check the relevant path for open_basedir in symlink()
authorArnaud Le Blanc <lbarnaud@php.net>
Mon, 11 Aug 2008 15:31:01 +0000 (15:31 +0000)
committerArnaud Le Blanc <lbarnaud@php.net>
Mon, 11 Aug 2008 15:31:01 +0000 (15:31 +0000)
ext/standard/link.c
ext/standard/tests/file/symlink_to_symlink.phpt
tests/security/open_basedir_symlink.phpt

index 054a74223781bf9d016d22899ac8431404a756f5..5fe4b8739b222b5ddbbbd20cac2f8cad033e2352 100644 (file)
@@ -49,6 +49,7 @@
 
 #include "safe_mode.h"
 #include "php_link.h"
+#include "php_string.h"
 
 /* {{{ proto string readlink(string filename)
    Return the target of a symbolic link */
@@ -115,6 +116,8 @@ PHP_FUNCTION(symlink)
        int ret;
        char source_p[MAXPATHLEN];
        char dest_p[MAXPATHLEN];
+       char dirname[MAXPATHLEN];
+       size_t len;
 
        if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &topath, &frompath) == FAILURE) {
                WRONG_PARAM_COUNT;
@@ -122,7 +125,15 @@ PHP_FUNCTION(symlink)
        convert_to_string_ex(topath);
        convert_to_string_ex(frompath);
 
-       if (!expand_filepath(Z_STRVAL_PP(frompath), source_p TSRMLS_CC) || !expand_filepath(Z_STRVAL_PP(topath), dest_p TSRMLS_CC)) {
+       if (!expand_filepath(Z_STRVAL_PP(frompath), source_p TSRMLS_CC)) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
+               RETURN_FALSE;
+       }
+
+       memcpy(dirname, source_p, sizeof(source_p));
+       len = php_dirname(dirname, strlen(dirname));
+
+       if (!expand_filepath_ex(Z_STRVAL_PP(topath), dest_p, dirname, len TSRMLS_CC)) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
                RETURN_FALSE;
        }
index 7e2062812f344745a923a4f43722136c6c2690f7..c672a5ab304d1677603417f77b0bbad2da6ae928 100644 (file)
@@ -1,5 +1,11 @@
 --TEST--
 symlink() using a relative path, and symlink() to a symlink
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+    die('skip no symlinks on Windows');
+}
+?>
 --FILE--
 <?php
 $prefix = __FILE__;
index 3b3f1d571ff4b595314591400fcfd1219c1198c0..3aaa07b820e61f21b829f5277553f85cd5251eb2 100644 (file)
@@ -31,6 +31,12 @@ $target = ($directory."/test/ok/ok.txt");
 
 var_dump(symlink($target, $symlink));
 var_dump(unlink($symlink));
+
+var_dump(mkdir("ok2"));
+$symlink = ($directory."/test/ok/ok2/ok.txt");
+var_dump(symlink("../ok.txt", $symlink)); // $target == (dirname($symlink)."/".$target) == ($directory."/test/ok/ok.txt");
+var_dump(unlink($symlink));
+
 test_open_basedir_after("symlink");
 ?>
 --CLEAN--
@@ -74,5 +80,8 @@ Warning: symlink(): open_basedir restriction in effect. File(%s/test/bad) is not
 bool(false)
 bool(true)
 bool(true)
+bool(true)
+bool(true)
+bool(true)
 *** Finished testing open_basedir configuration [symlink] ***