From 4704c09c7c2fe1bcc544239ef3646e0d326e19cc Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 21 May 2015 01:22:26 +0200 Subject: [PATCH 1/2] Fix #50678: files extracted by ZipArchive class lost their original mtime Let's restore the mtime; by the way, neither ctime nor atime are stored by libzip, so we can't restore these. --- ext/zip/php_zip.c | 11 +++++++++++ ext/zip/tests/bug50678.phpt | 20 ++++++++++++++++++++ ext/zip/tests/bug50678.zip | Bin 0 -> 122 bytes 3 files changed, 31 insertions(+) create mode 100644 ext/zip/tests/bug50678.phpt create mode 100644 ext/zip/tests/bug50678.zip diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 7c17fb983aa2..131cefb1eafa 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -150,6 +150,9 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil size_t path_cleaned_len; cwd_state new_state; zend_string *file_basename; + struct utimbuf newtimebuf; + struct utimbuf *newtime = &newtimebuf; + php_stream_wrapper *wrapper; new_state.cwd = CWD_STATE_ALLOC(1); new_state.cwd[0] = '\0'; @@ -262,6 +265,14 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil php_stream_close(stream); n = zip_fclose(zf); + /* try to set mtime of extracted file; don't mind if that fails */ + newtime->modtime = sb.mtime; + newtime->actime = time(NULL); + wrapper = php_stream_locate_url_wrapper(fullpath, NULL, 0); + if (wrapper && wrapper->wops) { + wrapper->wops->stream_metadata(wrapper, fullpath, PHP_STREAM_META_TOUCH, newtime, NULL); + } + done: efree(fullpath); zend_string_release(file_basename); diff --git a/ext/zip/tests/bug50678.phpt b/ext/zip/tests/bug50678.phpt new file mode 100644 index 000000000000..8e66d435b51f --- /dev/null +++ b/ext/zip/tests/bug50678.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #50678 (files extracted by ZipArchive class loose their original modified time) +--FILE-- +open(__DIR__ . '/bug50678.zip'); +$zip->extractTo($dest); +$zip->close(); +var_dump(filemtime($dest . '/bug50678.txt')); +?> +--CLEAN-- + +--EXPECT-- +int(1432163274) diff --git a/ext/zip/tests/bug50678.zip b/ext/zip/tests/bug50678.zip new file mode 100644 index 0000000000000000000000000000000000000000..c5f12a3121f544258c1db4622d793e320cb4733e GIT binary patch literal 122 zcmWIWW@Zs#0D<2eTiw76D8U1ylS Date: Fri, 17 Jul 2015 00:35:47 +0200 Subject: [PATCH 2/2] fixed test to cater to limitation that extracted files which are not writable won't have proper mtimes --- ext/zip/tests/bug50678.phpt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ext/zip/tests/bug50678.phpt b/ext/zip/tests/bug50678.phpt index 8e66d435b51f..919412e4b38d 100644 --- a/ext/zip/tests/bug50678.phpt +++ b/ext/zip/tests/bug50678.phpt @@ -1,5 +1,9 @@ --TEST-- Bug #50678 (files extracted by ZipArchive class loose their original modified time) +--SKIPIF-- + --FILE-- open(__DIR__ . '/bug50678.zip'); $zip->extractTo($dest); $zip->close(); -var_dump(filemtime($dest . '/bug50678.txt')); +$filename = $dest . '/bug50678.txt'; +// check that the mtime is properly set, if the extracted file is writable +var_dump(!is_writable($filename) || filemtime($filename) == 1432163274); ?> --CLEAN-- --EXPECT-- -int(1432163274) +bool(true)