<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>al_make_path_canonical() issue</title>
		<link>http://www.allegro.cc/forums/view/615467</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Sun, 21 Jun 2015 06:02:47 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Currently <span class="source-code"><a href="http://www.allegro.cc/manual/al_make_path_canonical"><span class="a">al_make_path_canonical</span></a><span class="k2">(</span><span class="k2">)</span></span> doesn&#39;t collapse &quot;..&quot; pieces.  The documentation says this is by design to preserve symlink semantics, however there are certain sandboxing scenarios where collapsing the &quot;..&quot; anyway (without resolving symlinks) would actually be desirable.  Could we add an optional boolean parameter to the function for this purpose?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Fri, 19 Jun 2015 10:04:28 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/615467/1014097#target">Bruce Pascoe</a> said:</div><div class="quote"><p>Currently al_make_path_canonical() doesn&#39;t collapse &quot;..&quot; pieces. The documentation says this is by design to preserve symlink semantics, however there are certain sandboxing scenarios where collapsing the &quot;..&quot; anyway (without resolving symlinks) would actually be desirable. Could we add an optional boolean parameter to the function for this purpose?</p></div></div><p>

I don&#39;t know how safe that is. collapsing .. means it&#39;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&#39;t think we can just add a parameter, probably have to add another function for that.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sat, 20 Jun 2015 23:32:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Just to clarify, if there is a symlink:</p><p>data/trees -&gt; /myart/treegame/rendered</p><p>And the game has a path like this:</p><p>data/trees/../tree.png</p><p>Then the actual file is at: /myart/treegame/rendered/../tree.png which is /myart/treegame/tree.png</p><p>If you collapse the &quot;..&quot; instead you end up with: data/tree.png which does not exist.</p><p>What we could do is add a function &quot;al_make_path_absolute&quot; 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&#39;m not sure if we want such a specialized function.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Sat, 20 Jun 2015 23:41:14 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Yes, I&#39;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:</p><p>data/trees/../tree.png</p><p>Because the game is sandboxed, the game engine <i>expects</i> that to refer to the same file as data/tree.png, following the symlink would violate that assumption.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Sat, 20 Jun 2015 23:59:10 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Is there a specific reason you even need to bother?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sun, 21 Jun 2015 00:02:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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:</p><p>images/ScottSucks.png<br />sounds/BGM/ThePromise.ogg</p><p>If a game within that package does, say:</p><p><span class="source-code">var image <span class="k3">=</span> <span class="k1">new</span> Image<span class="k2">(</span><span class="s">"../fatpig_images/maggie.png"</span><span class="k2">)</span><span class="k2">;</span></span></p><p>The path the engine constructs for this internally ends up being:</p><p>images/../fatpig_images/maggie.png</p><p>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:</p><p>fatpig_images/maggie.png</p><p>Which Allegro won&#39;t do.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Sun, 21 Jun 2015 00:10:16 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I tend to prefer to have a manager that takes &quot;names&quot; of resources, generally they look like filenames, and can be resolved as such, but don&#39;t have to be. And they generally never have ..&#39;s in them.</p><p>Your example doesn&#39;t make all that much sense to me. A .. should still resolve in a &quot;package&quot;, at least assuming if your package api is sane.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sun, 21 Jun 2015 00:28:05 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Indeed, that&#39;s the way I have it set up, there&#39;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&#39;t care where the resource is.</p><p>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&#39;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&#39;m having trouble.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Sun, 21 Jun 2015 00:38:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>How do you treat leading ..&#39;s? say your whole path is &#39;../foo/bar/baz.xyz&#39;, you can&#39;t just remove it and have it be proper...</p><p>Ignoring that, here&#39;s something you can use:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="p">#include &lt;allegro5/allegro5.h&gt;</span>
<span class="number">  2</span><span class="p">#include &lt;stdio.h&gt;</span>
<span class="number">  3</span>
<span class="number">  4</span><span class="k1">bool</span> make_path_canonical_ex<span class="k2">(</span>ALLEGRO_PATH <span class="k3">*</span>path<span class="k2">)</span>
<span class="number">  5</span><span class="k2">{</span>
<span class="number">  6</span>  <span class="k1">unsigned</span> i<span class="k2">;</span>
<span class="number">  7</span>  ALLEGRO_ASSERT<span class="k2">(</span>path<span class="k2">)</span><span class="k2">;</span>
<span class="number">  8</span>
<span class="number">  9</span>  <span class="k1">for</span> <span class="k2">(</span>i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> <a href="http://www.allegro.cc/manual/al_get_path_num_components"><span class="a">al_get_path_num_components</span></a><span class="k2">(</span>path<span class="k2">)</span><span class="k2">;</span> <span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 10</span>    <span class="k1">if</span> <span class="k2">(</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_754.html" target="_blank">strcmp</a><span class="k2">(</span><a href="http://www.allegro.cc/manual/al_get_path_component"><span class="a">al_get_path_component</span></a><span class="k2">(</span>path, i<span class="k2">)</span>, <span class="s">"."</span><span class="k2">)</span> <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span>
<span class="number"> 11</span>    <span class="k2">{</span>
<span class="number"> 12</span>      <a href="http://www.allegro.cc/manual/al_remove_path_component"><span class="a">al_remove_path_component</span></a><span class="k2">(</span>path, i<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 13</span>    <span class="k2">}</span>
<span class="number"> 14</span>    <span class="k1">else</span> <span class="k1">if</span><span class="k2">(</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_754.html" target="_blank">strcmp</a><span class="k2">(</span><a href="http://www.allegro.cc/manual/al_get_path_component"><span class="a">al_get_path_component</span></a><span class="k2">(</span>path, i<span class="k2">)</span>, <span class="s">".."</span><span class="k2">)</span> <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span>
<span class="number"> 15</span>    <span class="k2">{</span>
<span class="number"> 16</span>      <a href="http://www.allegro.cc/manual/al_remove_path_component"><span class="a">al_remove_path_component</span></a><span class="k2">(</span>path, i<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 17</span>      <span class="k1">if</span><span class="k2">(</span>i <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span>
<span class="number"> 18</span>      <span class="k2">{</span>
<span class="number"> 19</span>        i--<span class="k2">;</span>
<span class="number"> 20</span>        <a href="http://www.allegro.cc/manual/al_remove_path_component"><span class="a">al_remove_path_component</span></a><span class="k2">(</span>path, i<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 21</span>      <span class="k2">}</span>
<span class="number"> 22</span>    <span class="k2">}</span>
<span class="number"> 23</span>    <span class="k1">else</span>
<span class="number"> 24</span>    <span class="k2">{</span>
<span class="number"> 25</span>      i<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span>
<span class="number"> 26</span>    <span class="k2">}</span>
<span class="number"> 27</span>  <span class="k2">}</span>
<span class="number"> 28</span>  
<span class="number"> 29</span>  <span class="k1">return</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number"> 30</span><span class="k2">}</span>
<span class="number"> 31</span>
<span class="number"> 32</span><span class="k1">void</span> test_path<span class="k2">(</span><span class="k1">const</span> <span class="k1">char</span> <span class="k3">*</span>pstr<span class="k2">)</span>
<span class="number"> 33</span><span class="k2">{</span>
<span class="number"> 34</span>  ALLEGRO_PATH <span class="k3">*</span>path <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_create_path"><span class="a">al_create_path</span></a><span class="k2">(</span>pstr<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 35</span>  <a href="http://www.allegro.cc/manual/al_make_path_canonical"><span class="a">al_make_path_canonical</span></a><span class="k2">(</span>path<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 36</span>  
<span class="number"> 37</span>  <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"path: '%s' -&gt; '%s'\n"</span>, pstr, <a href="http://www.allegro.cc/manual/al_path_cstr"><span class="a">al_path_cstr</span></a><span class="k2">(</span>path, ALLEGRO_NATIVE_PATH_SEP<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 38</span><span class="k2">}</span>
<span class="number"> 39</span>
<span class="number"> 40</span><span class="k1">int</span> main<span class="k2">(</span><span class="k1">int</span> argc, <span class="k1">char</span> <span class="k3">*</span><span class="k3">*</span>argv<span class="k2">)</span>
<span class="number"> 41</span><span class="k2">{</span>
<span class="number"> 42</span>  <a href="http://www.allegro.cc/manual/al_init"><span class="a">al_init</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 43</span>  
<span class="number"> 44</span>  test_path<span class="k2">(</span><span class="s">"../foo/bar/baz.zyz"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 45</span>  test_path<span class="k2">(</span><span class="s">"../foo/bar/../baz.xyz"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 46</span>  test_path<span class="k2">(</span><span class="s">"foo/../baz.xyz"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 47</span>  test_path<span class="k2">(</span><span class="s">"/foo/bar/../baz.xyz"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 48</span>  
<span class="number"> 49</span>  <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 50</span><span class="k2">}</span>
</div></div><p>
Not 100% tested, but that shows at least those types of paths work.</p><pre>moose@balsa:~/projects$ ./al_make_path_canonical_ex 
path: &#39;../foo/bar/baz.zyz&#39; -&gt; &#39;foo/bar/baz.zyz&#39;
path: &#39;../foo/bar/../baz.xyz&#39; -&gt; &#39;foo/baz.xyz&#39;
path: &#39;foo/../baz.xyz&#39; -&gt; &#39;baz.xyz&#39;
path: &#39;/foo/bar/../baz.xyz&#39; -&gt; &#39;/foo/baz.xyz&#39;
</pre><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sun, 21 Jun 2015 03:55:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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&#39;s the same deal as, say C:\..\maggie.fat.</p><p>Thanks for the code though, that should work fine. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Sun, 21 Jun 2015 04:42:12 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That code will remove the leading &quot;empty&quot; component that tells the code that that&#39;s an absolute path. So C:\..\file.ext may actually become &quot;file.ext&quot;.</p><p>I actually just meant &quot;..\foo\file.ext&quot;, as removing .. cant remove something before it, and removing .. in that case makes the path pretty meaningless.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sun, 21 Jun 2015 05:04:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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:</p><p>images/tiles/tree.png</p><p>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 &quot;..&quot; collapsing is sufficient.</p><p>Honestly I wasn&#39;t aware of al_remove_component() etc.  For whatever reason I assumed Allegro paths were like strings, mostly immutable.  So thanks again!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bruce Pascoe)</author>
		<pubDate>Sun, 21 Jun 2015 06:00:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Yeah, the whole idea behind the path api is to make paths mutable, and more useful, especially cross platform.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sun, 21 Jun 2015 06:02:47 +0000</pubDate>
	</item>
</rss>
