make it more explicit that caret/decaret are for encoding tags into URL paths
This commit is contained in:
parent
fb80509be9
commit
da42b19d6b
8 changed files with 70 additions and 73 deletions
|
@ -72,16 +72,6 @@ class PageRequestEvent extends Event
|
|||
// break the path into parts
|
||||
$args = explode('/', $path);
|
||||
|
||||
// voodoo so that an arg can contain a slash; is
|
||||
// this still needed?
|
||||
if (strpos($path, "^") !== false) {
|
||||
$unescaped = [];
|
||||
foreach ($args as $part) {
|
||||
$unescaped[] = _decaret($part);
|
||||
}
|
||||
$args = $unescaped;
|
||||
}
|
||||
|
||||
$this->args = $args;
|
||||
$this->arg_count = count($args);
|
||||
}
|
||||
|
@ -152,7 +142,7 @@ class PageRequestEvent extends Event
|
|||
{
|
||||
$search_terms = [];
|
||||
if ($this->count_args() === 2) {
|
||||
$search_terms = Tag::explode($this->get_arg(0));
|
||||
$search_terms = Tag::explode(Tag::decaret($this->get_arg(0)));
|
||||
}
|
||||
return $search_terms;
|
||||
}
|
||||
|
|
|
@ -152,7 +152,6 @@ class Tag
|
|||
return $tag_array;
|
||||
}
|
||||
|
||||
|
||||
public static function sqlify(string $term): string
|
||||
{
|
||||
global $database;
|
||||
|
@ -165,4 +164,51 @@ class Tag
|
|||
// $term = str_replace("?", "_", $term);
|
||||
return $term;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kind of like urlencode, but using a custom scheme so that
|
||||
* tags always fit neatly between slashes in a URL. Use this
|
||||
* when you want to put an arbitrary tag into a URL.
|
||||
*/
|
||||
public static function caret(string $input): string
|
||||
{
|
||||
$to_caret = [
|
||||
"^" => "^",
|
||||
"/" => "s",
|
||||
"\\" => "b",
|
||||
"?" => "q",
|
||||
"&" => "a",
|
||||
];
|
||||
|
||||
foreach($to_caret as $from => $to) {
|
||||
$input = str_replace($from, '^' . $to, $input);
|
||||
}
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this when you want to get a tag out of a URL
|
||||
*/
|
||||
public static function decaret(string $str): string
|
||||
{
|
||||
$from_caret = [
|
||||
"^" => "^",
|
||||
"s" => "/",
|
||||
"b" => "\\",
|
||||
"q" => "?",
|
||||
"a" => "&",
|
||||
];
|
||||
|
||||
$out = "";
|
||||
$length = strlen($str);
|
||||
for ($i=0; $i<$length; $i++) {
|
||||
if ($str[$i] == "^") {
|
||||
$i++;
|
||||
$out .= $from_caret[$str[$i]] ?? '';
|
||||
} else {
|
||||
$out .= $str[$i];
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -449,32 +449,9 @@ function int_escape(?string $input): int
|
|||
*/
|
||||
function url_escape(?string $input): string
|
||||
{
|
||||
/*
|
||||
Shish: I have a feeling that these three lines are important, possibly for searching for tags with slashes in them like fate/stay_night
|
||||
green-ponies: indeed~
|
||||
|
||||
$input = str_replace('^', '^^', $input);
|
||||
$input = str_replace('/', '^s', $input);
|
||||
$input = str_replace('\\', '^b', $input);
|
||||
|
||||
/* The function idn_to_ascii is used to support Unicode domains / URLs as well.
|
||||
See here for more: http://php.net/manual/en/function.filter-var.php
|
||||
However, it is only supported by PHP version 5.3 and up
|
||||
|
||||
if (function_exists('idn_to_ascii')) {
|
||||
return filter_var(idn_to_ascii($input), FILTER_SANITIZE_URL);
|
||||
} else {
|
||||
return filter_var($input, FILTER_SANITIZE_URL);
|
||||
}
|
||||
*/
|
||||
if (is_null($input)) {
|
||||
return "";
|
||||
}
|
||||
$input = str_replace('^', '^^', $input);
|
||||
$input = str_replace('/', '^s', $input);
|
||||
$input = str_replace('\\', '^b', $input);
|
||||
$input = str_replace('?', '^q', $input);
|
||||
$input = str_replace('&', '^a', $input);
|
||||
$input = rawurlencode($input);
|
||||
return $input;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class PolyfillsTest extends \PHPUnit\Framework\TestCase
|
|||
|
||||
public function test_url_escape()
|
||||
{
|
||||
$this->assertEquals(url_escape("^\o/^"), "%5E%5E%5Ebo%5Es%5E%5E");
|
||||
$this->assertEquals(url_escape("^\o/^"), "%5E%5Co%2F%5E");
|
||||
$this->assertEquals(url_escape(null), "");
|
||||
}
|
||||
|
||||
|
|
19
core/tests/tag.test.php
Normal file
19
core/tests/tag.test.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php declare(strict_types=1);
|
||||
require_once "core/imageboard/tag.php";
|
||||
|
||||
class TagTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function test_caret()
|
||||
{
|
||||
$this->assertEquals("foo", Tag::decaret("foo"));
|
||||
$this->assertEquals("foo?", Tag::decaret("foo^q"));
|
||||
$this->assertEquals("a^b/c\\d?e&f", Tag::decaret("a^^b^sc^bd^qe^af"));
|
||||
}
|
||||
|
||||
public function test_decaret()
|
||||
{
|
||||
$this->assertEquals("foo", Tag::caret("foo"));
|
||||
$this->assertEquals("foo^q", Tag::caret("foo?"));
|
||||
$this->assertEquals("a^^b^sc^bd^qe^af", Tag::caret("a^b/c\\d?e&f"));
|
||||
}
|
||||
}
|
|
@ -606,41 +606,6 @@ function _fatal_error(Exception $e): void
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn ^^ into ^ and ^s into /
|
||||
*
|
||||
* Necessary because various servers and various clients
|
||||
* think that / is special...
|
||||
*/
|
||||
function _decaret(string $str): string
|
||||
{
|
||||
$out = "";
|
||||
$length = strlen($str);
|
||||
for ($i=0; $i<$length; $i++) {
|
||||
if ($str[$i] == "^") {
|
||||
$i++;
|
||||
if ($str[$i] == "^") {
|
||||
$out .= "^";
|
||||
}
|
||||
if ($str[$i] == "s") {
|
||||
$out .= "/";
|
||||
}
|
||||
if ($str[$i] == "b") {
|
||||
$out .= "\\";
|
||||
}
|
||||
if ($str[$i] == "q") {
|
||||
$out .= "?";
|
||||
}
|
||||
if ($str[$i] == "a") {
|
||||
$out .= "&";
|
||||
}
|
||||
} else {
|
||||
$out .= $str[$i];
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function _get_user(): User
|
||||
{
|
||||
global $config, $page;
|
||||
|
|
|
@ -25,7 +25,7 @@ class Index extends Extension
|
|||
if ($event->page_matches("post/list")) {
|
||||
if (isset($_GET['search'])) {
|
||||
// implode(explode()) to resolve aliases and sanitise
|
||||
$search = url_escape(Tag::implode(Tag::explode($_GET['search'], false)));
|
||||
$search = url_escape(Tag::caret(Tag::implode(Tag::explode($_GET['search'], false))));
|
||||
if (empty($search)) {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/list/1"));
|
||||
|
|
|
@ -9,7 +9,7 @@ class RSSImages extends Extension
|
|||
$title = $config->get_string(SetupConfig::TITLE);
|
||||
|
||||
if (count($event->search_terms) > 0) {
|
||||
$search = html_escape(implode(' ', $event->search_terms));
|
||||
$search = url_escape(Tag::caret(Tag::implode($event->search_terms)));
|
||||
$page->add_html_header("<link id=\"images\" rel=\"alternate\" type=\"application/rss+xml\" ".
|
||||
"title=\"$title - Images with tags: $search\" href=\"".make_link("rss/images/$search/1")."\" />");
|
||||
} else {
|
||||
|
|
Reference in a new issue