]> granicus.if.org Git - php/commitdiff
MFH: Fixed bug #32160 (copying a file into itself leads to data loss).
authorIlia Alshanetsky <iliaa@php.net>
Wed, 20 Jul 2005 19:26:31 +0000 (19:26 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Wed, 20 Jul 2005 19:26:31 +0000 (19:26 +0000)
NEWS
ext/standard/file.c
ext/standard/tests/file/bug32160.phpt [new file with mode: 0644]
ext/standard/tests/file/bug32160.txt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index fed9475d0225e8bf37346745c5abf7376e006c56..4733543647548392beb3609bedef256873a50a38 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,11 @@
 PHP 4                                                                      NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2005, Version 4.4.1
-- Fixed bug #33648 (Using --with-regex=system causes compile failure). (Andrei)
 - Fixed bug #33673 (Added detection for partially uploaded files). (Ilia)
+- Fixed bug #33648 (Using --with-regex=system causes compile failure). (Andrei)
 - Fixed bug #33156 (cygwin version of setitimer doesn't accept ITIMER_PROF).
   (Nuno)
+- Fixed bug #32160 (copying a file into itself leads to data loss). (Ilia)
 - Fixed bug #31158 (array_splice on $GLOBALS crashes). (Dmitry)
 
 11 Jul 2005, Version 4.4.0
index b1ad6f742da82fce0664fa8579cf65b0bb994068..4e1e17c3c5d47d0b52f40eeec5302c6f935cab73 100644 (file)
@@ -2141,6 +2141,56 @@ PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC)
 {
        php_stream *srcstream = NULL, *deststream = NULL;
        int ret = FAILURE;
+       php_stream_statbuf src_s, dest_s;
+
+       switch (php_stream_stat_path(src, &src_s)) {
+               case -1:
+                       /* non-statable stream */
+                       goto safe_to_copy;
+                       break;
+               case 0:
+                       break;
+               default: /* failed to stat file, does not exist? */
+                       return ret;
+       }
+       if (php_stream_stat_path(dest, &dest_s) != 0) {
+               goto safe_to_copy;
+       }
+       if (!src_s.sb.st_ino || !dest_s.sb.st_ino) {
+               goto no_stat;
+       }
+       if (src_s.sb.st_ino == dest_s.sb.st_ino && src_s.sb.st_dev == dest_s.sb.st_dev) {
+               return ret;
+       } else {
+               goto safe_to_copy;
+       }
+no_stat:
+       {
+               char *sp, *dp;
+               int res;
+               
+               if ((sp = expand_filepath(src, NULL TSRMLS_CC)) == NULL) {
+                       return ret;
+               }
+               if ((dp = expand_filepath(dest, NULL TSRMLS_CC)) == NULL) {
+                       efree(sp);
+                       goto safe_to_copy;
+               }
+
+               res = 
+#ifndef PHP_WIN32              
+                       !strcmp(sp, dp);
+#else
+                       !strcasecmp(sp, dp);
+#endif 
+
+               efree(sp);
+               efree(dp);
+               if (res) {
+                       return ret;
+               }
+       }
+safe_to_copy:
 
        srcstream = php_stream_open_wrapper(src, "rb",
                                STREAM_DISABLE_OPEN_BASEDIR | REPORT_ERRORS,
diff --git a/ext/standard/tests/file/bug32160.phpt b/ext/standard/tests/file/bug32160.phpt
new file mode 100644 (file)
index 0000000..e496803
--- /dev/null
@@ -0,0 +1,14 @@
+--TEST--
+Bug #32160 (copying a file into itself leads to data loss)
+--FILE--
+<?php
+$path = dirname(__FILE__) . "/bug32160.txt";
+var_dump(copy($path, $path));
+chdir(dirname(__FILE__));
+var_dump(copy($path, "bug32160.txt"));
+var_dump(copy("bug32160.txt", "bug32160.txt"));
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(false)
diff --git a/ext/standard/tests/file/bug32160.txt b/ext/standard/tests/file/bug32160.txt
new file mode 100644 (file)
index 0000000..1e4a6b5
--- /dev/null
@@ -0,0 +1 @@
+copy test