Currently al_make_path_canonical() doesn't collapse ".." pieces. The documentation says this is by design to preserve symlink semantics, however there are certain sandboxing scenarios where collapsing the ".." anyway (without resolving symlinks) would actually be desirable. Could we add an optional boolean parameter to the function for this purpose?

Currently al_make_path_canonical() doesn't collapse ".." pieces. The documentation says this is by design to preserve symlink semantics, however there are certain sandboxing scenarios where collapsing the ".." anyway (without resolving symlinks) would actually be desirable. Could we add an optional boolean parameter to the function for this purpose?

I don't know how safe that is. collapsing .. means it'd have to remove the previous dir in the chain, but the parent in the dir string may not actually be the correct parent... I don't think we can just add a parameter, probably have to add another function for that.

Elias

Just to clarify, if there is a symlink:

data/trees -> /myart/treegame/rendered

And the game has a path like this:

data/trees/../tree.png

Then the actual file is at: /myart/treegame/rendered/../tree.png which is /myart/treegame/tree.png

If you collapse the ".." instead you end up with: data/tree.png which does not exist.

What we could do is add a function "al_make_path_absolute" which is aware of symlinks and returns the absolute path without any symlinks to a file. Right now nothing similar to this exists at all though and I'm not sure if we want such a specialized function.

Bruce Pascoe

Yes, I'm aware of the symlink issue. However, there are certain scenarios, e.g. sandboxing, where this is actually desirable. Say you want to sandbox your game to a specific directory, now within the game engine the game constructs a path like this:

data/trees/../tree.png

Because the game is sandboxed, the game engine expects that to refer to the same file as data/tree.png, following the symlink would violate that assumption.

Thomas Fjellstrom

Is there a specific reason you even need to bother?

Bruce Pascoe

Yes, my game engine, minisphere, has the ability to run a game from a package file, where within the package index each file is stored with its full path as its filename, like this:

images/ScottSucks.pngsounds/BGM/ThePromise.ogg

If a game within that package does, say:

var image =new Image("../fatpig_images/maggie.png");

The path the engine constructs for this internally ends up being:

images/../fatpig_images/maggie.png

When running an unpackaged game, this succeeds because the operating system resolves it. But for a package, the engine returns a file not found because the index lookup fails. In order for it to succeed, the path has to be canonized to:

fatpig_images/maggie.png

Which Allegro won't do.

Thomas Fjellstrom

I tend to prefer to have a manager that takes "names" of resources, generally they look like filenames, and can be resolved as such, but don't have to be. And they generally never have ..'s in them.

Your example doesn't make all that much sense to me. A .. should still resolve in a "package", at least assuming if your package api is sane.

Bruce Pascoe

Indeed, that's the way I have it set up, there's a sandbox manager within the game which takes a resource path and resolves it for the underlying FS type (local or package). The rest of the engine doesn't care where the resource is.

The trouble is, I have to be compatible with the Sphere engine, which accepts paths containing .. For games running from the local FS, this works fine. But the SPK package format (which I didn't invent) stores all resources with their full path as a filename--there is no concept of a directory in an SPK package. So in order to allow .. in a resource name, the path has to be pre-resolved. Thats where I'm having trouble.

Thomas Fjellstrom

How do you treat leading ..'s? say your whole path is '../foo/bar/baz.xyz', you can't just remove it and have it be proper...

At least in my case, the sandbox manager will never generate a path with leading .. as all asset loading functions in Sphere are defined as being relative to some subdirectory or another, which is prepended to the path given by the user (hence why I have to support .. in the first place). Even if it did though, removing it would be fine as the game directory is defined as the root, so it's the same deal as, say C:\..\maggie.fat.

Thanks for the code though, that should work fine.

Thomas Fjellstrom

That code will remove the leading "empty" component that tells the code that that's an absolute path. So C:\..\file.ext may actually become "file.ext".

I actually just meant "..\foo\file.ext", as removing .. cant remove something before it, and removing .. in that case makes the path pretty meaningless.

Bruce Pascoe

Yeah, I already handle absolute paths separately because they always refer to the physical file system. The package manager never sees them. The package manager only sees paths of the form:

images/tiles/tree.png

Within the context of a package, the path above is actually absolute, even though it would be considered relative in most other contexts. So for this use case there will never be an issue of an absolute path being converted to a (meaningless) relative one, and naive ".." collapsing is sufficient.

Honestly I wasn't aware of al_remove_component() etc. For whatever reason I assumed Allegro paths were like strings, mostly immutable. So thanks again!

Thomas Fjellstrom

Yeah, the whole idea behind the path api is to make paths mutable, and more useful, especially cross platform.