diff --git a/include/wx/filename.h b/include/wx/filename.h index ef108760e2..3906804521 100644 --- a/include/wx/filename.h +++ b/include/wx/filename.h @@ -72,7 +72,17 @@ enum wxPathNormalize wxPATH_NORM_ABSOLUTE = 0x0010, // make the path absolute wxPATH_NORM_LONG = 0x0020, // make the path the long form (MSW-only) wxPATH_NORM_SHORTCUT = 0x0040, // resolve the shortcut, if it is a shortcut - wxPATH_NORM_ALL = 0x00ff & ~wxPATH_NORM_CASE + + // Don't use this constant, it used to correspond to the default + // Normalize() behaviour but this is deprecated now. + wxPATH_NORM_DEPR_OLD_DEFAULT= 0x00ff & ~wxPATH_NORM_CASE, + + // This constant name is misleading, as it doesn't really include all the + // flags above, so its use is discouraged, please use the flags you want + // explicitly instead. + wxPATH_NORM_ALL + wxDEPRECATED_ATTR("specify the wanted flags explicitly to avoid surprises") + = wxPATH_NORM_DEPR_OLD_DEFAULT }; // what exactly should GetPath() return? @@ -341,15 +351,21 @@ public: // operations on the path - // normalize the path: with the default flags value, the path will be - // made absolute, without any ".." and "." and all environment - // variables will be expanded in it + // normalize the path using the specified normalizations, use + // MakeAbsolute() for a simpler form applying the standard ones // // this may be done using another (than current) value of cwd - bool Normalize(int flags = wxPATH_NORM_ALL, + bool Normalize(int flags, const wxString& cwd = wxEmptyString, wxPathFormat format = wxPATH_NATIVE); + // using wxPATH_NORM_ALL may give unexpected results, so avoid using + // this function and call Normalize(wxPATH_NORM_ENV_VARS | ...) + // explicitly if you really need environment variables expansion + wxDEPRECATED_MSG("specify the wanted flags explicitly to avoid surprises") + bool Normalize() + { return Normalize(wxPATH_NORM_DEPR_OLD_DEFAULT); } + // get a path path relative to the given base directory, i.e. opposite // of Normalize // diff --git a/interface/wx/filename.h b/interface/wx/filename.h index 01642d4d78..3c4842a126 100644 --- a/interface/wx/filename.h +++ b/interface/wx/filename.h @@ -54,10 +54,20 @@ enum wxSizeConvention */ enum wxPathNormalize { - //! Replace environment variables with their values. - //! wxFileName understands both Unix and Windows (but only under Windows) environment - //! variables expansion: i.e. @c "$var", @c "$(var)" and @c "${var}" are always understood - //! and in addition under Windows @c "%var%" is also. + /** + Replace environment variables with their values. + + wxFileName understands both Unix and Windows (but only under Windows) environment + variables expansion: i.e. @c "$var", @c "$(var)" and @c "${var}" are always understood + and in addition under Windows @c "%var%" is also. + + Note that when this flag is used, dollar or percent signs may be + escaped with backslashes to prevent them from being used for the + variable expansion, meaning that normalizing any path with a directory + starting with a dollar sign under Windows can give unexpected results, + as normalizing @c c:\\foo\\$bar results in @c c:\\foo$bar. Because of + this, using this flag with arbitrary paths is not recommended. + */ wxPATH_NORM_ENV_VARS = 0x0001, wxPATH_NORM_DOTS = 0x0002, //!< Squeeze all @c ".." and @c ".". @@ -80,7 +90,16 @@ enum wxPathNormalize wxPATH_NORM_SHORTCUT = 0x0040, //!< Resolve the shortcut, if it is a shortcut (Windows only). - //! A value indicating all normalization flags except for @c wxPATH_NORM_CASE. + /** + Flags used by wxFileName::Normalize() by default. + + This includes all normalization flags except for @c wxPATH_NORM_CASE + and notably does include @c wxPATH_NORM_ENV_VARS which may yield + unexpected results, as described above. Because of this, this flag is + deprecated and shouldn't be used in the new code and the existing code + should be reviewed to check if expanding environment variables is + really needed. + */ wxPATH_NORM_ALL = 0x00ff & ~wxPATH_NORM_CASE }; @@ -1080,7 +1099,9 @@ public: Normalize the path. With the default flags value, the path will be made absolute, without - any ".." and "." and all environment variables will be expanded in it. + any ".." and ".", and, for the Unix format paths, any occurrences of + tilde (@c ~) character will be replaced with the home directory of the + user following it. Notice that in some rare cases normalizing a valid path may result in an invalid wxFileName object. E.g. normalizing "./" path using @@ -1091,6 +1112,9 @@ public: @param flags The kind of normalization to do with the file name. It can be any or-combination of the ::wxPathNormalize enumeration values. + These values should be explicitly specified, omitting them uses the + deprecated wxPATH_NORM_ALL value which is not recommended, see + wxPathNormalize enum for more details. @param cwd If not empty, this directory will be used instead of current working directory in normalization (see @c wxPATH_NORM_ABSOLUTE). @@ -1099,7 +1123,7 @@ public: @return @true if normalization was successfully or @false otherwise. */ - bool Normalize(int flags = wxPATH_NORM_ALL, + bool Normalize(int flags, const wxString& cwd = wxEmptyString, wxPathFormat format = wxPATH_NATIVE); diff --git a/src/common/filename.cpp b/src/common/filename.cpp index 8688e92a66..f54144cd9b 100644 --- a/src/common/filename.cpp +++ b/src/common/filename.cpp @@ -1841,8 +1841,20 @@ bool wxFileName::SameAs(const wxFileName& filepath, wxPathFormat format) const // get cwd only once - small time saving wxString cwd = wxGetCwd(); - fn1.Normalize(wxPATH_NORM_ALL | wxPATH_NORM_CASE, cwd, format); - fn2.Normalize(wxPATH_NORM_ALL | wxPATH_NORM_CASE, cwd, format); + + // apply really all normalizations here + const int normAll = + wxPATH_NORM_ENV_VARS | + wxPATH_NORM_DOTS | + wxPATH_NORM_TILDE | + wxPATH_NORM_CASE | + wxPATH_NORM_ABSOLUTE | + wxPATH_NORM_LONG | + wxPATH_NORM_SHORTCUT + ; + + fn1.Normalize(normAll, cwd, format); + fn2.Normalize(normAll, cwd, format); if ( fn1.GetFullPath() == fn2.GetFullPath() ) return true; diff --git a/tests/filename/filenametest.cpp b/tests/filename/filenametest.cpp index 73d927d59f..776acfc6ea 100644 --- a/tests/filename/filenametest.cpp +++ b/tests/filename/filenametest.cpp @@ -36,6 +36,10 @@ #include "testfile.h" #include "testdate.h" +// Use a hack to keep using wxPATH_NORM_ALL in this test code without getting +// deprecation warnings for it. +#define wxPATH_NORM_ALL wxPATH_NORM_DEPR_OLD_DEFAULT + // ---------------------------------------------------------------------------- // test data // ---------------------------------------------------------------------------- @@ -317,6 +321,13 @@ TEST_CASE("wxFileName::Normalize", "[filename]") { ".\\foo", wxPATH_NORM_LONG, ".\\foo", wxPATH_DOS }, { "..\\Makefile.in", wxPATH_NORM_LONG, "..\\Makefile.in", wxPATH_DOS }, { "..\\foo", wxPATH_NORM_LONG, "..\\foo", wxPATH_DOS }, + + // test default behaviour with deprecated wxPATH_NORM_ALL +#ifdef __WINDOWS__ + { "%ABCDEF%/g/h/i", wxPATH_NORM_ALL, "CWD/abcdef/g/h/i", wxPATH_UNIX }, +#else + { "$(ABCDEF)/g/h/i", wxPATH_NORM_ALL, "CWD/abcdef/g/h/i", wxPATH_UNIX }, +#endif }; // set the env var ABCDEF