Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

boost::filesystem::native

46 views
Skip to first unread message

Christopher J. Pisz

unread,
Nov 10, 2016, 2:25:47 PM11/10/16
to
I did a Google search to see how to check if a given path is valid,
preferably using boost.

It brought me here:

http://stackoverflow.com/questions/10426671/how-to-check-if-path-is-valid-in-boostfilesystem

Great! I say to myself.
I then Google up the boost doc here:
http://www.boost.org/doc/libs/1_62_0/libs/filesystem/doc/portability_guide.htm

I then write myself a test:



#include <iostream>
#include <sstream>

#include <boost/filesystem.hpp>

int main()
{
const std::string test1 = "D:\\Programing Projects\\Git
Workspace\\Common\\x64\\Debug";
const std::string test2 = "D:\Programing Projects\\Git
Workspace\\Common\\x64\\Debug\\";
const std::string test3 = "D:/Programing Projects/Git
Workspace/Common/x64/Debug";
const std::string test4 = "D:/Programing Projects/Git
Workspace/Common/x64/Debug/";

if (!boost::filesystem::native(test1))
{
std::cout << "Boost says the following path is not valid
for the native operating system: " << test1 << std::endl;
}

if (!boost::filesystem::native(test2))
{
std::cout << "Boost says the following path is not valid
for the native operating system: " << test2 << std::endl;
}

if (!boost::filesystem::native(test3))
{
std::cout << "Boost says the following path is not valid for
the native operating system: " << test3 << std::endl;
}

if (!boost::filesystem::native(test4))
{
std::cout << "Boost says the following path is not valid
for the native operating system: " << test4 << std::endl;

}

return 0;
}

The Test's Output:

Boost says the following path is not valid for the native operating
system: D:\Programing Projects\Git Workspace\Common\x64\Debug
Boost says the following path is not valid for the native operating
system: D:Programing Projects\Git Workspace\Common\x64\Debug\
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug/

What is wrong with that path that it says it is not valid for my native
Windows 10 operating system?

Paavo Helde

unread,
Nov 10, 2016, 5:02:43 PM11/10/16
to
On 10.11.2016 21:25, Christopher J. Pisz wrote:
> I did a Google search to see how to check if a given path is valid,
> preferably using boost.
>
> It brought me here:
>
> http://stackoverflow.com/questions/10426671/how-to-check-if-path-is-valid-in-boostfilesystem
>
>
> Great! I say to myself.
> I then Google up the boost doc here:
> http://www.boost.org/doc/libs/1_62_0/libs/filesystem/doc/portability_guide.htm

All this page appears to talk about names, not paths. I.e. these
functions are meant for checking the path elements, not the full paths.
"Git workspace" is a valid file or directory name, for example.

hth
Paavo




Christopher J. Pisz

unread,
Nov 10, 2016, 5:07:49 PM11/10/16
to
Wow that would be both misleading and somewhat worthless.
Does boost have anything to check if the entire path would be a valid,
where valid means it could be used to create a file or directory, but
does not necessarily point to one?

If not, I guess it's regex time?

Christopher J. Pisz

unread,
Nov 10, 2016, 5:47:44 PM11/10/16
to
On 11/10/2016 4:02 PM, Paavo Helde wrote:
I am not conviced that is the problem is we consider this test on Windows:

#include <iostream>
#include <sstream>

#include <boost/filesystem.hpp>


// Just a garbage console application to do some manual testing.
int main()
{
std::cout << boost::filesystem::native("C://PATH") << std::endl;
std::cout << boost::filesystem::native("C:/PATH") << std::endl;
std::cout << boost::filesystem::native("C:\\PATH") << std::endl;
std::cout << boost::filesystem::native("\\PATH") << std::endl;
std::cout << boost::filesystem::native("/PATH") << std::endl;
std::cout << boost::filesystem::native("//PATH") << std::endl;

std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"C://PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"C:/PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"C:\\PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"\\PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"/PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"//PATH")) << std::endl;

return 0;
}


It seems to report the first 3 of the wide string paths are valid.
This set of boost functions are really confusing.



Öö Tiib

unread,
Nov 10, 2016, 6:04:09 PM11/10/16
to
On Friday, 11 November 2016 00:47:44 UTC+2, Christopher J. Pisz wrote:
> This set of boost functions are really confusing.

It is not confusing. The assholes making OS X, Windows and Linux
are far more confusing. WTF do they want? To screw everybody? Why?

Did you for now sort out "getting error info"?

Christopher J. Pisz

unread,
Nov 10, 2016, 6:13:11 PM11/10/16
to
hehe. Yea I was able to sort out the error codes.

Paavo Helde

unread,
Nov 11, 2016, 5:58:50 AM11/11/16
to
This is because of the abused reinterpret_cast:

reinterpret_cast<char*>(L"C://PATH")

is pretty much equivalent to (Windows is little-endian):

"C"

and "C" is indeed a valid file name in Windows.

Why on earth do you think you can convert wide strings to narrow strings
just by casting?

Cheers
Paavo


Christopher J. Pisz

unread,
Nov 11, 2016, 3:47:55 PM11/11/16
to
I don't. :)

Some other guy was suggesting on stack overflow, that is the intended
use of this boost function. I just did not know how to explain to him
that it surely wasn't, aside from "bad". Now I do!

Now I am convinced. I guess there is no way for me to really validate a
path aside from using it.

Thanks for clearing it up.



Paavo Helde

unread,
Nov 11, 2016, 6:28:55 PM11/11/16
to
That's a good idea. You cannot validate fully anyway because the file
may reside in any kind of network-mapped directory of a foreign
filesystem with its own rules. The filenames are also often abused to
pass through some extended functionality, so if your validator is
over-eager it might forbid some potentially useful names like
\\?\UNC\foo\bar or file://C|/foo/bar.

BTW, the declaration of boost::filesystem::native() in Boost headers is
commented as:

// name_checks
// These functions are holdovers from version 1. It isn't clear they
have much
// usefulness, or how to generalize them for later versions.

So it seems this is just random crap left over from older times. Indeed,
as mentioned in SO comments, it even accepts * as a valid filename
character!

Anyway, the native Windows SDK interface works with strings in UTF-16
encoding, so any function defined in terms of std::string and claiming
to work with Windows filenames is pretty suspicious (unless it is
clearly stated that they use UTF-8 encoding, which is indeed capable of
properly representing UTF-16).

I see that boost::filesystem::path uses 16-bit wchar_t on Windows, which
makes a lot more sense.

Cheers
Paavo

0 new messages