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