[filesystem] filesystem::absolute() doesn't work with ../relative_path or ./relative_path

In boost 1.47.0 filesystem v3, boost::filesystem::absolute only appends the relative path to base path. It should also remove "./" from relative paths and "backtrack" on base path if relative path contains "../../" etc. For example, Input: "d:\current\path" ".\..\relative\path" Result obtained: "d:\current\path\.\..\relative\path" Desired result: "d:\current\relative\path" I have created a trac ticket for the same: https://svn.boost.org/trac/boost/ticket/5988 SG

On Fri, Oct 07, 2011 at 09:52:32AM +0530, Sachin Garg wrote:
In boost 1.47.0 filesystem v3, boost::filesystem::absolute only appends the relative path to base path. It should also remove "./" from relative paths and "backtrack" on base path if relative path contains "../../" etc.
That is outside the scope of the function. In order to properly handle `..`, it would have to hit the filesystem to find out the information needed to canonicalize the path, as you cannot naïvely assume that a `..` is equivalent to removing parts of the path. Thanks to symlinks and hardlinks, you can find yourself in a completely different area of the filesystems. Resolving paths is something that functions that need to resolve paths do, not a simple mechanical absolute(). If the function did this (which it shouldn't), it would be completely unusable if the path does not represent assets on the local machine, assets rooted somewhere else, assets in a virtual filesystem, and so on. It would also have a lot more error cases, like not being able to traverse the directory hierarchy. All in all, the behaviour is a feature, not a bug. In any way, the documentation explains exactly how the resulting path is composed: http://www.boost.org/doc/libs/1_47_0/libs/filesystem/v3/doc/reference.html#a... -- Lars Viklund | zao@acc.umu.se

On Fri, Oct 7, 2011 at 2:43 PM, Lars Viklund
In boost 1.47.0 filesystem v3, boost::filesystem::absolute only appends
relative path to base path. It should also remove "./" from relative
On Fri, Oct 07, 2011 at 09:52:32AM +0530, Sachin Garg wrote: the paths
and "backtrack" on base path if relative path contains "../../" etc.
That is outside the scope of the function.
In order to properly handle `..`, it would have to hit the filesystem to find out the information needed to canonicalize the path, as you cannot naïvely assume that a `..` is equivalent to removing parts of the path. Thanks to symlinks and hardlinks, you can find yourself in a completely different area of the filesystems. Resolving paths is something that functions that need to resolve paths do, not a simple mechanical absolute().
If the function did this (which it shouldn't), it would be completely unusable if the path does not represent assets on the local machine, assets rooted somewhere else, assets in a virtual filesystem, and so on.
It would also have a lot more error cases, like not being able to traverse the directory hierarchy.
All in all, the behaviour is a feature, not a bug.
In any way, the documentation explains exactly how the resulting path is composed:
http://www.boost.org/doc/libs/1_47_0/libs/filesystem/v3/doc/reference.html#a...
I do understand that it is complicated to resolve paths but at the same time I feel that the main motivation to have boost::filesystem is that it takes care of most such complications under a cross-platform API. It is not a string manipulation library and is aware of underlying filesystem's properties. When both the base and relative paths are valid and together point to a valid location, the result of absolute shouldn't be an invalid path like d:\base\path\.\..\..\file (while using such a path on windows cmd or bash shell works, it fails when such a path is passed to APIs under windows or linux). SG

On Fri, Oct 07, 2011 at 05:32:47PM +0530, Sachin Garg wrote:
On Fri, Oct 7, 2011 at 2:43 PM, Lars Viklund
wrote: In boost 1.47.0 filesystem v3, boost::filesystem::absolute only appends
relative path to base path. It should also remove "./" from relative
On Fri, Oct 07, 2011 at 09:52:32AM +0530, Sachin Garg wrote: the paths
and "backtrack" on base path if relative path contains "../../" etc.
That is outside the scope of the function.
In order to properly handle `..`, it would have to hit the filesystem to find out the information needed to canonicalize the path, as you cannot naïvely assume that a `..` is equivalent to removing parts of the path. Thanks to symlinks and hardlinks, you can find yourself in a completely different area of the filesystems. Resolving paths is something that functions that need to resolve paths do, not a simple mechanical absolute().
If the function did this (which it shouldn't), it would be completely unusable if the path does not represent assets on the local machine, assets rooted somewhere else, assets in a virtual filesystem, and so on.
It would also have a lot more error cases, like not being able to traverse the directory hierarchy.
All in all, the behaviour is a feature, not a bug.
In any way, the documentation explains exactly how the resulting path is composed:
http://www.boost.org/doc/libs/1_47_0/libs/filesystem/v3/doc/reference.html#a...
I do understand that it is complicated to resolve paths but at the same time I feel that the main motivation to have boost::filesystem is that it takes care of most such complications under a cross-platform API. It is not a string manipulation library and is aware of underlying filesystem's properties.
When both the base and relative paths are valid and together point to a valid location, the result of absolute shouldn't be an invalid path like d:\base\path\.\..\..\file (while using such a path on windows cmd or bash shell works, it fails when such a path is passed to APIs under windows or linux).
So file a feature request asking for a resolve() or canonicalize() function, that does what you want. Note that requiring filesystem state will introduce a lot of complications. What would resolve(p) do if part of the path doesn't exist yet (denotes a filename that should be used to open an output stream to, or some other valid reason)? What should it do if that part of the path is before the `..`? After the `..`? In any way, changing the semantics of absolute() would be a bug. -- Lars Viklund | zao@acc.umu.se

On 7 October 2011 15:23, Lars Viklund
So file a feature request asking for a resolve() or canonicalize() function, that does what you want.
A canonical function is going to be added: http://lists.boost.org/Archives/boost/2011/10/186567.php

On Fri, Oct 7, 2011 at 05:02, Sachin Garg
I do understand that it is complicated to resolve paths but at the same time I feel that the main motivation to have boost::filesystem is that it takes care of most such complications under a cross-platform API. It is not a string manipulation library and is aware of underlying filesystem's properties.
I should be able to use the same path object not only for "normal" filesystem operations, but also in my FTP client, in my HTTP server, in my game's resource manager, ... To me, it's very important that there's a very clear line between path manipulation functions and filesystem manipulation functions, where something like canonical() is the latter. Personally I think there should even be an interface and a "host_filesystem" implementation for the latter, so things like a VFS or pack format have a logical starting point, but that's a separate issue. ~ Scott
participants (4)
-
Daniel James
-
Lars Viklund
-
Sachin Garg
-
Scott McMurray