Absolute paths without drive letter triggers assertion on Win

Absolute paths without drive letters are supported on Windows and are assumed to point to the current drive.

However, if you run the following code:

juce::File filename("\\Users\\John\\foo.txt");

Will generate an assertion within File::parseAbsolutePath() even though the file does exist.

 

 

It’s still a relative path to your current drive. If the program is run from “D:” it probably won’t work.

According to the Microsoft documentation, this is a type of absolute path on Windows.

https://msdn.microsoft.com/en-nz/library/windows/desktop/aa365247(v=vs.85).aspx#fully_qualified_vs._relative_paths

It is just context-dependent, but not relative. I think the issue is that this case is not taken into account in the code, so when no drive letter is specified or does not start with "\\" it will just assert.

 

Regardless of whether it's technically an absolute path or not, you shouldn't hit the assertion, because

a) If you're really hard-coding a pathname like your example above, then you shouldn't be! If you want something like the home folder, then you should get it via File::getSpecialLocation so that it works on all machines

b) Or if you're taking unknown user-input as a pathname, then you should be parsing it as a relative to whatever base folder you want to use, e.g. most commonly you'd say something like File::getCurrentWorkingDirectory().getChildFile (myUserSpecifiedPathString)

 

Hi guys,

There's no any hardcoded path, that was just an illustrative example to show how to reproduce the bug ;)

The fact is that the assertion is likely to be hit providing a valid path on Windows.

Just a bit of background information, we have some classes wrapping the juc::File class. The case which is triggering the bug involves a path passed by the user via a scripting interface, so we cannot really control that. 

The only way for us to circunvent this is currently hacking it by adding the current drive letter on Windows builds, which is not pretty.

Thank you.

 

 

The case which is triggering the bug involves a path passed by the user via a scripting interface, so we cannot really control that. 

Yeah, that's exactly what I was talking about in the second point in my post above.

In this case the input from the user can be anything (doesn't have to be restricted to a specific location), so the only way circunventing the issue is as I said earlier.

So you guys think this bug is worth solving or are you going to leave it as it is?

No, what you said earlier is NOT the only (or correct) way to avoid the assertion!

Read the answer that I already gave you: You should use getChildFile to parse their input relative to a base path that makes sense for your app.

I understand how that workaround would work, thank you.

We will use it for the moment but it would be great if this issue would be solved guys.

What I suggested isn't a "workaround"!! It's the correct way to express what you're trying to do!

When you're parsing user input, then it's possible that they'll type a relative path, so to convert their text into an absolute path, you must supply a base folder against which it will be parsed. The File constructor that takes a bare string is not intended for possibly-relative strings, as it says in the comments for it!

I agree but its not always obvious when you need to do this.

For example if you use JUCE_LIVE_CONSTANT with the Intel C++ compiler on Windows 7 with VS2013 the source file path that is passed into the LiveValueBase constructor is a relative path and JUCE asserts in the same way. This doesn't happen using Visual Studio alone. In that case the path is absolute.

So this is an illustration of a bug in JUCE that arises from this behaviour.

In the case where JUCE knows it requires an absolute path, for example JUCE_LIVE_CONSTANT, would it not be better to automatically use File::getCurrentWorkingDirectory().getChildFile (...) to convert it to an absolute path rather than just failing?  If you feel the need, in debug only you could still assert, warning that a relative path is being converted to absolute, maybe with a preprocessor flag to allow this check to be disabled.

 

huh? JUCE_LIVE_CONSTANT just deals with strings, not files. How could it possibly know whether you intend to use a particular string as a filename?

The Intel C++ compiler defines the name of the source file __FILE__ as a relative path not an absolute path so in LiveConstantEditor::getValue this path is relative and hence when it gets to the LiveValueBase constructor it asserts and hence you can't use JUCE_LIVE_CONSTANT unless you edit manually edit juce_LiveConstantEditor.cpp to automatically convert these paths to absolute.

I was using this as an example of a case in JUCE where it was not anticipated that a filepath in windows could be be relative not absolute.

 

 

 

Oh, I see, I thought you were talking about wrapping a filename using JUCE_LIVE_CONSTANT.

Well, it's true I never anticipated that __FILE__ would be anything other than an absolute path, because IMHO it's completely nuts for a compiler to produce a partial path.. Within a piece of compiled code, there's no way to possibly know what that path should be relative to! All other compilers I've seen use absolute paths FWIW.

But this actually proves my point.. There isn't a correct "fix" for this case, because the running code can't possibly know where the original source code was compiled from, so it's impossible to supply a correct base path from which this path could be correctly determined. So the correct thing for the program to do is exactly what you're seeing: i.e. a run-time assertion warning about undefined behaviour, rather than having some kind of hard-coded fallback path in the code which may or may not end up resolving to the right file.

Actually, you can tell Visual Studio to use absolute paths.

There is a property called "Use Full Paths", which you have to set. Alternatively you can use the command line option /FC.

More details in the following MSDN article: https://msdn.microsoft.com/en-us/library/027c4t2s%28v=vs.120%29.aspx

 

EDIT: Oh, just realized, that you are talking about the Intel Compiler and not about Visual Studio :-) Well anyways, could be interesting for Visual Studio users.

Actually when I wrote my first email I thought that JUCE asserted in release as well as debug. However I realise now I was wrong so what JUCE does is exactly what I think it should do in general - automatically convert from a relative path in release and assert in debug.

For the JUCE_LIVE_CONSTANT issue there is no workaround from Intel. If the code doesn't mess with the current working directory before the path needs to be resolved then simply converting using the working directory in LiveValueBase constructor and valueList::EditorWindow::UpdateItems should work and did work for me.