diff --git a/index.php b/index.php index 5c2d685..166193c 100644 --- a/index.php +++ b/index.php @@ -1,12 +1,14 @@ "); } - $t = new \htmgem\GemTextTranslate_html(@file_get_contents("index.gmi"), true, "/htmgem"); - echo $t->getFullHtml(); + $gt_html = new \htmgem\GemTextTranslate_html(@file_get_contents("index.gmi"), true, "/htmgem"); + echo \htmgem\html\getFullHtml($gt_html); exit(); } $documentRoot = $_SERVER['DOCUMENT_ROOT']; +/** + * Provides index.gmi if no page given + */ if (!preg_match("/\.gmi$/", $url)) { if ($url[-1] == "/") $url = $url."index.gmi"; @@ -49,20 +54,14 @@ switch(true) { if ($go404) { error_log("HtmGem: 404 $url $filePath"); http_response_code(404); - $page404 = << .. πŸ”„ πŸ”„ -EOF; - $t = new \htmgem\GemTextTranslate_html($page404); - echo $t->getFullHtml(); + $page404 = \htmgem\html\get404GmiPage("Page not found", $url); + $gt_html = new \htmgem\GemTextTranslate_html($page404); + echo \htmgem\html\getFullHtml($gt_html); exit(); } # to false only if textDecoration=0 in the URL -$textDecoration = "0" != @$_REQUEST['textDecoration']; +$gt_htmlextDecoration = "0" != @$_REQUEST['textDecoration']; $fileContents = @file_get_contents($filePath); # Removes the Byte Order Mark @@ -106,11 +105,11 @@ if ($urlRewriting) $baseUrl = null; else $baseUrl = dirname($url); -$t = new \htmgem\GemTextTranslate_html($fileContents, $textDecoration, $baseUrl); +$gt_html = new \htmgem\GemTextTranslate_html($fileContents, $gt_htmlextDecoration, $baseUrl); if ("none" == $style) { - $t->addCss(""); + $gt_html->addCss(""); } elseif ("/" == @$style[0]) { - $t->addCss($style); + $gt_html->addCss($style); } elseif (empty($style)) { $parts = pathinfo($filePath); $localCss = $parts["filename"].".css"; @@ -118,12 +117,12 @@ if ("none" == $style) { if (file_exists($localCssFilePath)) { # Warning, using htmhem.php?url=… will make $localCss not found # as the path is relative to htmgem.php and not / ! - $t->addCss($localCss); + $gt_html->addCss($localCss); } } else { #TODO: regex check for $style - $t->addCss("/htmgem/css/$style.css"); + $gt_html->addCss("/htmgem/css/$style.css"); } -echo $t->getFullHtml(); +echo \htmgem\html\getFullHtml($gt_html); ?> diff --git a/lib-htmgem.php b/lib-htmgem.inc.php similarity index 94% rename from lib-htmgem.php rename to lib-htmgem.inc.php index 0edd6f9..8dc0847 100644 --- a/lib-htmgem.php +++ b/lib-htmgem.inc.php @@ -197,6 +197,9 @@ class GemtextTranslate_html { $this->cssList []= $css; } + function getCss() { return $this->cssList; } + function getTitle() { return $this->pageTitle; } + const NARROW_NO_BREAK_SPACE = " "; const DASHES ="β€’" # U+2012 Figure Dash @@ -263,14 +266,20 @@ class GemtextTranslate_html { $text = preg_replace("/ +/", " ", $text); } - protected static function resolve_path($path) { + /** + * Resolve $path interpretating / . and .. + * @param $path str + * @returns "/" if .. goes above the limit + */ + public static function resolve_path($path) { + if (empty($path)) return ""; $absolute = "/"==$path[0]; $parts = array_filter(explode("/", $path), 'strlen'); $chuncks = array(); foreach ($parts as $part) { if ('.' == $part) continue; if ('..' == $part) { - array_pop($chuncks); + if (is_null(array_pop($chuncks))) return "/"; } else { $chuncks[] = $part; } @@ -374,34 +383,6 @@ class GemtextTranslate_html { $this->translatedGemtext = $output; } - function getFullHtml() { - if (!$this->cssList) - $css = array("/htmgem/css/htmgem.css"); - else - $css = $this->cssList; - $output = << - - -{$this->pageTitle} - -EOL; - foreach ($css as $c) { - $output .= "\n\n"; - } - $output .= << -\n -EOL; - $output .= $this->translatedGemtext; - $output .= "\n\n"; - - echo $output; - } - - public function __toString() { - return $this->translatedGemtext; - } } // GemTextTranslate_html ?> diff --git a/lib-html.inc.php b/lib-html.inc.php new file mode 100644 index 0000000..6069a6f --- /dev/null +++ b/lib-html.inc.php @@ -0,0 +1,44 @@ +getCss(); + if (!$css) $css = array("/htmgem/css/htmgem.css"); + $output = << + + +{$gt_html->getTitle()} + +EOL; + foreach ($css as $c) { + $output .= "\n\n"; + } + $output .= << +\n +EOL; + $output .= $gt_html->translatedGemtext; + $output .= "\n\n"; + + return $output; +} + +function get404Gmipage($message, $url) { + return << .. πŸ”„ πŸ”„ +EOF; +} + +?> diff --git a/tests/cli/parse_gemtext.php b/tests/cli/parse_gemtext.php index 16c08e6..9d601f7 100644 --- a/tests/cli/parse_gemtext.php +++ b/tests/cli/parse_gemtext.php @@ -2,7 +2,7 @@ $fileName = $argv[1]; -require_once dirname(__FILE__)."/../lib-htmgem.php"; +require_once dirname(__FILE__)."/../lib-htmgem.inc.php"; $text = file_get_contents($fileName); $parsedGemtext = \htmgem\gemtextParser($text); diff --git a/tests/cli/translate_to_gemtext.php b/tests/cli/translate_to_gemtext.php index f66ad45..63bba80 100644 --- a/tests/cli/translate_to_gemtext.php +++ b/tests/cli/translate_to_gemtext.php @@ -2,7 +2,7 @@ $fileName = $argv[1]; -require_once dirname(__FILE__)."/../../lib-htmgem.php"; +require_once dirname(__FILE__)."/../../lib-htmgem.inc.php"; $text = file_get_contents($fileName); $gt_gemtext = new \htmgem\GemtextTranslate_gemtext($text); diff --git a/tests/cli/translate_to_html.php b/tests/cli/translate_to_html.php index 3fc27c0..6905211 100644 --- a/tests/cli/translate_to_html.php +++ b/tests/cli/translate_to_html.php @@ -2,7 +2,7 @@ $fileName = $argv[1]; -require_once dirname(__FILE__)."/../../lib-htmgem.php"; +require_once dirname(__FILE__)."/../../lib-htmgem.inc.php"; $text = file_get_contents($fileName); $gt_gemtext = new \htmgem\GemtextTranslate_html($text); diff --git a/tests/miscTest.php b/tests/miscTest.php new file mode 100644 index 0000000..beb607f --- /dev/null +++ b/tests/miscTest.php @@ -0,0 +1,96 @@ +assertSame( + \htmgem\GemtextTranslate_html::resolve_path(""), + "", + "empty link" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("test"), + "test", + "single word" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path(" "), + " ", + "single space" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path(" A B "), + " A B ", + "several space" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("/"), + "/", + "one slash" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("//"), + "/", + "two slashes" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("/////"), + "/", + "five slashes" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("one/"), + "one", + "strip the last slash" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("/two"), + "/two", + "slash at the beginning" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("/two/"), + "/two", + "slash at the beginning and the end" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("one/two/"), + "one/two", + "only the last slash remains" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("one/two/three//"), + "one/two/three", + "strip the last slashes" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("one/../"), + "", + "empty one" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("one/two/../"), + "one", + "empty one two" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("one/two/../.."), + "", + "empty one two twice" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("one/../two/./../three"), + "three", + "waltz" + ); + $this->assertSame( + \htmgem\GemtextTranslate_html::resolve_path("one/../.."), + "/", + "directory traversal" + ); + } + +} diff --git a/tests/parserTest.php b/tests/parserTest.php index 1e37e71..ba38ee6 100644 --- a/tests/parserTest.php +++ b/tests/parserTest.php @@ -1,7 +1,7 @@ translatedGemtext); } final class translateToHtmlTest extends TestCase {