Skip to content

Instantly share code, notes, and snippets.

@chernjie
Created December 6, 2012 04:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chernjie/4221865 to your computer and use it in GitHub Desktop.
Save chernjie/4221865 to your computer and use it in GitHub Desktop.
Bug fix for relative directory removal
<?php
$examples = array(
'../' => ''
, '/../' => ''
, 'abc/../' => 'abc'
, '../def' => 'def'
, '/../def' => 'def'
, 'abc/../../def' => 'abc/def'
, 'abc../' => 'abc..'
, 'abc/def../' => 'abc/def..'
, 'abc/def../ghi' => 'abc/def../ghi'
, 'abc/def../ghi' => 'abc/def../ghi'
, 'abc//def' => 'abc/def'
, 'abc///def' => 'abc/def'
, 'abc////def' => 'abc/def'
, '0/abc' => '0/abc'
, '00/abc' => '00/abc'
, 'abc/0' => 'abc/0'
, 'abc/00' => 'abc/00'
, 'abc/0/def' => 'abc/0/def'
, 'abc/00/def' => 'abc/00/def'
);
foreach($examples as $uri=>$expectedResult)
{
// $testResult = str_replace(array('//', '../'), '/', trim($uri, '/')) //fail
// $testResult = preg_replace('#(^|/)\.\./|/+#', '/', $uri); //fail
// $testResult = remove_relative_explode($uri);
$testResult = remove_relative($uri);
//echo $testResult;
// remove leading and trailing slash if any, expectedResult does not care
echo trim($testResult, '/') == $expectedResult ? '.' : 'F';
echo " " . $uri . "\n";
}
function remove_relative($uri)
{
$uris = array();
$tok = strtok($uri, '/');
while ($tok !== FALSE)
{
if (( ! empty($tok) OR $tok === '0') && $tok !== '..')
{
$uris[] = $tok;
}
$tok = strtok('/');
}
return implode('/', $uris);
}
function remove_relative_explode($url)
{
$uris = array();
$toks = explode('/', $url);
foreach ($toks as $tok)
($tok != '..' && ! empty($tok) || $tok === '0') && $uris[] = $tok;
return implode('/', $uris);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment