Fix bug #65701: Do not use cache for file file copy

This commit is contained in:
Boro Sitnikovski 2014-04-14 10:02:11 +02:00 committed by Stanislav Malyshev
parent 53c68811ba
commit a18cec1b86
5 changed files with 63 additions and 27 deletions

9
NEWS
View File

@ -2,14 +2,15 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2014, PHP 5.4.29
- Core:
. Fixed bug #65701 (copy() doesn't work when destination filename is created
by tempnam()). (Boro Sitnikovski)
. Fixed bug #67072 (Echoing unserialized "SplFileObject" crash). (Anatol)
- DOM:
. Fixed bug #67081 (DOMDocumentType->internalSubset returns entire DOCTYPE tag,
not only the subset). (Anatol)
- Standard:
. Fixed bug #67072 (Echoing unserialized "SplFileObject" crash). (Anatol)
?? ??? 2014, PHP 5.4.28
- Core:

View File

@ -1657,7 +1657,7 @@ PHPAPI int php_copy_file_ctx(char *src, char *dest, int src_flg, php_stream_cont
return FAILURE;
}
switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET, &dest_s, ctx)) {
switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET | PHP_STREAM_URL_STAT_NOCACHE, &dest_s, ctx)) {
case -1:
/* non-statable stream */
goto safe_to_copy;

View File

@ -0,0 +1,30 @@
--TEST--
Test for bug #65701: copy() doesn't work when destination filename is created by tempnam()
--CREDITS--
Boro Sitnikovski <buritomath@yahoo.com>
--FILE--
<?php
$file_path = dirname(__FILE__) . "/bug65701/";
mkdir($file_path);
$src = $file_path . '/srcbug65701_file.txt';
$dst = tempnam($file_path, 'dstbug65701_file.txt');
file_put_contents($src, "Hello World");
copy($src, $dst);
var_dump(filesize($dst));
?>
--CLEAN--
<?php
$file_path = dirname(__FILE__) . "/bug65701/";
foreach (scandir($file_path) as $file) {
if (strpos($file, "bug65701") !== false) {
unlink($file_path . $file);
}
}
rmdir($file_path);
?>
--EXPECT--
int(11)

View File

@ -377,6 +377,7 @@ END_EXTERN_C()
/* Flags for url_stat method in wrapper ops */
#define PHP_STREAM_URL_STAT_LINK 1
#define PHP_STREAM_URL_STAT_QUIET 2
#define PHP_STREAM_URL_STAT_NOCACHE 4
/* change the blocking mode of stream: value == 1 => blocking, value == 0 => non-blocking. */
#define PHP_STREAM_OPTION_BLOCKING 1

View File

@ -1929,16 +1929,18 @@ PHPAPI int _php_stream_stat_path(char *path, int flags, php_stream_statbuf *ssb,
char *path_to_open = path;
int ret;
/* Try to hit the cache first */
if (flags & PHP_STREAM_URL_STAT_LINK) {
if (BG(CurrentLStatFile) && strcmp(path, BG(CurrentLStatFile)) == 0) {
memcpy(ssb, &BG(lssb), sizeof(php_stream_statbuf));
return 0;
}
} else {
if (BG(CurrentStatFile) && strcmp(path, BG(CurrentStatFile)) == 0) {
memcpy(ssb, &BG(ssb), sizeof(php_stream_statbuf));
return 0;
if (!(flags & PHP_STREAM_URL_STAT_NOCACHE)) {
/* Try to hit the cache first */
if (flags & PHP_STREAM_URL_STAT_LINK) {
if (BG(CurrentLStatFile) && strcmp(path, BG(CurrentLStatFile)) == 0) {
memcpy(ssb, &BG(lssb), sizeof(php_stream_statbuf));
return 0;
}
} else {
if (BG(CurrentStatFile) && strcmp(path, BG(CurrentStatFile)) == 0) {
memcpy(ssb, &BG(ssb), sizeof(php_stream_statbuf));
return 0;
}
}
}
@ -1946,19 +1948,21 @@ PHPAPI int _php_stream_stat_path(char *path, int flags, php_stream_statbuf *ssb,
if (wrapper && wrapper->wops->url_stat) {
ret = wrapper->wops->url_stat(wrapper, path_to_open, flags, ssb, context TSRMLS_CC);
if (ret == 0) {
/* Drop into cache */
if (flags & PHP_STREAM_URL_STAT_LINK) {
if (BG(CurrentLStatFile)) {
efree(BG(CurrentLStatFile));
if (!(flags & PHP_STREAM_URL_STAT_NOCACHE)) {
/* Drop into cache */
if (flags & PHP_STREAM_URL_STAT_LINK) {
if (BG(CurrentLStatFile)) {
efree(BG(CurrentLStatFile));
}
BG(CurrentLStatFile) = estrdup(path);
memcpy(&BG(lssb), ssb, sizeof(php_stream_statbuf));
} else {
if (BG(CurrentStatFile)) {
efree(BG(CurrentStatFile));
}
BG(CurrentStatFile) = estrdup(path);
memcpy(&BG(ssb), ssb, sizeof(php_stream_statbuf));
}
BG(CurrentLStatFile) = estrdup(path);
memcpy(&BG(lssb), ssb, sizeof(php_stream_statbuf));
} else {
if (BG(CurrentStatFile)) {
efree(BG(CurrentStatFile));
}
BG(CurrentStatFile) = estrdup(path);
memcpy(&BG(ssb), ssb, sizeof(php_stream_statbuf));
}
}
return ret;