[Boost-bugs] [Boost C++ Libraries] #12987: boost::filesystem::exists crashes

Subject: [Boost-bugs] [Boost C++ Libraries] #12987: boost::filesystem::exists crashes
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-04-24 16:19:34


#12987: boost::filesystem::exists crashes
------------------------------+------------------------
 Reporter: Leinad | Owner: bemandawes
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: filesystem
  Version: Boost 1.64.0 | Severity: Problem
 Keywords: |
------------------------------+------------------------
 {{{
 bool dummy = boost::filesystem::exists("C:\\alma.txt"); //1

 class Alma
 {
 public:
         ~Alma() { std::cout <<
 boost::filesystem::path("c:\\alma.txt").string() << std::endl; }
 };

 Alma a; //2

 int main(int argc, char* argv[])
 {
         Alma(); //3
         return 0;
 }
 }}}

 The reason for the crash is that "dummy" is initialised before
 "equal_string_ordinal_ic" in the unnamed namespace in operations.cpp. The
 fix (or a possible fix) is easy. I made operations.cpp a bit uglier by
 moving static stuff to "perms make_permissions(const path&, DWORD)":


 {{{
 perms make_permissions(const path& p, DWORD attr)
   {
     //this was in the unnamed namespace:
     static PtrRtlEqualUnicodeString rtl_equal_unicode_string_api =
 PtrRtlEqualUnicodeString(
       ::GetProcAddress(
         ::GetModuleHandleW(L"ntdll.dll"), "RtlEqualUnicodeString"));

     //this was in the unnamed namespace:
     static bool(*equal_string_ordinal_ic)(const wchar_t*, const wchar_t*,
 PtrRtlEqualUnicodeString) =
       rtl_equal_unicode_string_api ? equal_string_ordinal_ic_1 :
 equal_string_ordinal_ic_2;

     perms prms = fs::owner_read | fs::group_read | fs::others_read;
     if ((attr & FILE_ATTRIBUTE_READONLY) == 0)
       prms |= fs::owner_write | fs::group_write | fs::others_write;
     path ext = p.extension();
     if (equal_string_ordinal_ic(ext.c_str(), L".exe",
 rtl_equal_unicode_string_api)
       || equal_string_ordinal_ic(ext.c_str(), L".com",
 rtl_equal_unicode_string_api)
       || equal_string_ordinal_ic(ext.c_str(), L".bat",
 rtl_equal_unicode_string_api)
       || equal_string_ordinal_ic(ext.c_str(), L".cmd",
 rtl_equal_unicode_string_api))
       prms |= fs::owner_exe | fs::group_exe | fs::others_exe;
     return prms;
   }

 }}}

 I also changed the signatures of two locally used functions:

 {{{
 bool equal_string_ordinal_ic_1(const wchar_t* s1, const wchar_t* s2,
 PtrRtlEqualUnicodeString rtl_equal_unicode_string_api)

 bool equal_string_ordinal_ic_2(const wchar_t* s1, const wchar_t* s2,
 PtrRtlEqualUnicodeString)
 }}}


 And now that the static stuff is moved from the unnamed namespace to the
 make_permissions method there is no crash anymore.

 At least until I comment out (//1). Please note that (//3) is needed for
 the second type of crash.
 This second type of crash is not entirely new. There is a bug filed 5
 years ago. I think someone who is involved in developing boost::filesystem
 with this info (that the second type of crash does not occur if we call
 (//1) (supposed make_permissions has been fixed)) could sort out that old
 bug as well. [https://svn.boost.org/trac/boost/ticket/6638]

 This static initialisation/destruction looks a nasty business.

 compiler: vc14, static lib, statically linked runtime

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/12987>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-04-24 16:24:58 UTC