From ae1cc83f98b779eb3f01779d416bde994332efd3 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 4 Jan 2014 00:47:10 +0100 Subject: [PATCH 1/4] Fixed bug #66009 Failed compilation of PHP extension with C++ std library using VS 2012 Visual Studio 2012 includes sanity checks for C++11 features, see http://msdn.microsoft.com/en-us/library/vstudio/bb531344(v=vs.110).aspx To fix the 'inline' keyword redefinition for C++ in debug mode, the new macros ZEND_WIN32_KEEP_INLINE is introduced, ZEND_WIN32_FORCE_INLINE is automatically appended in release mode. --- TSRM/tsrm_config.w32.h | 9 +-------- Zend/zend_config.w32.h | 9 +++++++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/TSRM/tsrm_config.w32.h b/TSRM/tsrm_config.w32.h index 14c6443a03d..1443e7cca96 100644 --- a/TSRM/tsrm_config.w32.h +++ b/TSRM/tsrm_config.w32.h @@ -2,6 +2,7 @@ #define TSRM_CONFIG_W32_H #include <../main/config.w32.h> +#include "Zend/zend_config.w32.h" #define HAVE_UTIME 1 #define HAVE_ALLOCA 1 @@ -11,12 +12,4 @@ #include #include -#undef inline -#ifdef ZEND_WIN32_FORCE_INLINE -# define inline __forceinline -#else -# define inline -#endif - - #endif diff --git a/Zend/zend_config.w32.h b/Zend/zend_config.w32.h index f779a506e66..6ea67602b49 100644 --- a/Zend/zend_config.w32.h +++ b/Zend/zend_config.w32.h @@ -62,10 +62,15 @@ typedef unsigned int uint; /* This will cause the compilation process to be MUCH longer, but will generate * a much quicker PHP binary */ -#undef inline #ifdef ZEND_WIN32_FORCE_INLINE +/* _ALLOW_KEYWORD_MACROS is only relevant for C++ */ +# if (_MSC_VER >= 1700) && !defined(_ALLOW_KEYWORD_MACROS) +# define _ALLOW_KEYWORD_MACROS +# endif +# undef inline # define inline __forceinline -#else +#elif !defined(ZEND_WIN32_KEEP_INLINE) +# undef inline # define inline #endif From aaec199050ef61df0cd8abfb0e207e6c906295dd Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 4 Jan 2014 00:59:03 +0100 Subject: [PATCH 2/4] updated NEWS --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 86848b0dbbf..9112e0828ef 100644 --- a/NEWS +++ b/NEWS @@ -70,6 +70,10 @@ PHP NEWS - ZIP: . Fixed Bug #66321 (ZipArchive::open() ze_obj->filename_len not real). (Remi) +- Zend Engine + . Fixed bug #66009 (Failed compilation of PHP extension with C++ std + library using VS 2012). (Anatol) + 12 Dec 2013, PHP 5.5.7 - CLI server: From 4e7c9ea896e7aab8129701c7a0ddfbbab5b0f36a Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 4 Jan 2014 00:47:10 +0100 Subject: [PATCH 3/4] Fixed bug #66009 Failed compilation of PHP extension with C++ std library using VS 2012 Visual Studio 2012 includes sanity checks for C++11 features, see http://msdn.microsoft.com/en-us/library/vstudio/bb531344(v=vs.110).aspx To fix the 'inline' keyword redefinition for C++ in debug mode, the new macros ZEND_WIN32_KEEP_INLINE is introduced, ZEND_WIN32_FORCE_INLINE is automatically appended in release mode. --- TSRM/tsrm_config.w32.h | 9 +-------- Zend/zend_config.w32.h | 9 +++++++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/TSRM/tsrm_config.w32.h b/TSRM/tsrm_config.w32.h index 14c6443a03d..1443e7cca96 100644 --- a/TSRM/tsrm_config.w32.h +++ b/TSRM/tsrm_config.w32.h @@ -2,6 +2,7 @@ #define TSRM_CONFIG_W32_H #include <../main/config.w32.h> +#include "Zend/zend_config.w32.h" #define HAVE_UTIME 1 #define HAVE_ALLOCA 1 @@ -11,12 +12,4 @@ #include #include -#undef inline -#ifdef ZEND_WIN32_FORCE_INLINE -# define inline __forceinline -#else -# define inline -#endif - - #endif diff --git a/Zend/zend_config.w32.h b/Zend/zend_config.w32.h index f779a506e66..6ea67602b49 100644 --- a/Zend/zend_config.w32.h +++ b/Zend/zend_config.w32.h @@ -62,10 +62,15 @@ typedef unsigned int uint; /* This will cause the compilation process to be MUCH longer, but will generate * a much quicker PHP binary */ -#undef inline #ifdef ZEND_WIN32_FORCE_INLINE +/* _ALLOW_KEYWORD_MACROS is only relevant for C++ */ +# if (_MSC_VER >= 1700) && !defined(_ALLOW_KEYWORD_MACROS) +# define _ALLOW_KEYWORD_MACROS +# endif +# undef inline # define inline __forceinline -#else +#elif !defined(ZEND_WIN32_KEEP_INLINE) +# undef inline # define inline #endif From 3f7f72adb25786f51e7907e0d37f2e25bd5cf3dd Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 5 Jan 2014 19:05:04 +0100 Subject: [PATCH 4/4] improved the fix for bug #66395 - fixed the traverse vulnerability in case like c:d:file.txt - ensure paths containing NTFS streams are still worky --- ext/standard/string.c | 15 +++++++- .../basename_bug66395_variation2-win32.phpt | 36 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/file/basename_bug66395_variation2-win32.phpt diff --git a/ext/standard/string.c b/ext/standard/string.c index bf2df9a6121..c4e77f2f299 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1433,7 +1433,7 @@ PHPAPI void php_basename(const char *s, size_t len, char *suffix, size_t sufflen goto quit_loop; case 1: #if defined(PHP_WIN32) || defined(NETWARE) - if (*c == '/' || *c == '\\' || (*c == ':' && (c - s == 1))) { + if (*c == '/' || *c == '\\') { #else if (*c == '/') { #endif @@ -1441,6 +1441,19 @@ PHPAPI void php_basename(const char *s, size_t len, char *suffix, size_t sufflen state = 0; cend = c; } +#if defined(PHP_WIN32) || defined(NETWARE) + /* Catch relative paths in c:file.txt style. They're not to confuse + with the NTFS streams. This part ensures also, that no drive + letter traversing happens. */ + } else if ((*c == ':' && (c - comp == 1))) { + if (state == 0) { + comp = c; + state = 1; + } else { + cend = c; + state = 0; + } +#endif } else { if (state == 0) { comp = c; diff --git a/ext/standard/tests/file/basename_bug66395_variation2-win32.phpt b/ext/standard/tests/file/basename_bug66395_variation2-win32.phpt new file mode 100644 index 00000000000..05df79b02a0 --- /dev/null +++ b/ext/standard/tests/file/basename_bug66395_variation2-win32.phpt @@ -0,0 +1,36 @@ +--TEST-- +basename bug #66395 check drive traversing and NTFS streams +--SKIPIF-- + +--FILE-- + +==DONE== +--EXPECTF-- +y +y +notdriveletter:file.txt +hcd:c.txt +some.txt +f.txt +g.txt +g.txt +world:somestream +world:some.stream +world:some.stream:$DATA +world:my.stream:$DATA +world:c:$DATA +==DONE==