[core] use rawurlencode/decode consistently, deprecate caret system

This commit is contained in:
Shish 2023-12-24 21:12:59 +00:00 committed by Shish
parent be353450d8
commit 2ac243d20d
11 changed files with 37 additions and 76 deletions

View file

@ -103,7 +103,7 @@ class PageRequestEvent extends Event
{
$offset = $this->part_count + $n;
if ($offset >= 0 && $offset < $this->arg_count) {
return $this->args[$offset];
return rawurldecode($this->args[$offset]);
} else {
$nm1 = $this->arg_count - 1;
throw new UserErrorException("Requested an invalid page argument {$offset} / {$nm1}");
@ -144,7 +144,33 @@ class PageRequestEvent extends Event
{
$search_terms = [];
if ($this->count_args() === 2) {
$search_terms = Tag::explode(Tag::decaret($this->get_arg(0)));
$str = $this->get_arg(0);
// decode legacy caret-encoding just in case
// somebody has bookmarked such a URL
$from_caret = [
"^" => "^",
"s" => "/",
"b" => "\\",
"q" => "?",
"a" => "&",
"d" => ".",
];
$out = "";
$length = strlen($str);
for ($i = 0; $i < $length; $i++) {
if ($str[$i] == "^") {
$i++;
$out .= $from_caret[$str[$i]] ?? '';
} else {
$out .= $str[$i];
}
}
$str = $out;
// end legacy
$search_terms = Tag::explode($str);
}
return $search_terms;
}

View file

@ -187,7 +187,7 @@ function redirect_to_next_image(Image $image): void
global $page;
if (isset($_GET['search'])) {
$search_terms = Tag::explode(Tag::decaret($_GET['search']));
$search_terms = Tag::explode($_GET['search']);
$query = "search=" . url_escape($_GET['search']);
} else {
$search_terms = [];

View file

@ -273,53 +273,4 @@ 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",
"." => "d",
];
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" => "&",
"d" => ".",
];
$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;
}
}

View file

@ -10,20 +10,6 @@ require_once "core/imageboard/tag.php";
class TagTest extends 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"));
}
public function test_compare()
{
$this->assertFalse(Tag::compare(["foo"], ["bar"]));

View file

@ -17,7 +17,7 @@ class UrlsTest extends TestCase
search_link(["foo", "bar"])
);
$this->assertEquals(
"/test/post/list/cat%2A%20rating%3D%5Eq/1",
"/test/post/list/cat%2A%20rating%3D%3F/1",
search_link(["rating=?", "cat*"])
);
}

View file

@ -28,7 +28,7 @@ class Link
function search_link(array $terms = [], int $page = 1): string
{
if($terms) {
$q = rawurlencode(Tag::caret(Tag::implode($terms)));
$q = url_escape(Tag::implode($terms));
return make_link("post/list/$q/$page");
} else {
return make_link("post/list/$page");

View file

@ -78,8 +78,6 @@ and of course start organising your images :-)
$prev = $page_number - 1;
$next = $page_number + 1;
$u_tags = url_escape(Tag::implode($search_terms));
$h_prev = ($page_number <= 1) ? "Prev" : '<a href="'.search_link($search_terms, $prev).'">Prev</a>';
$h_index = "<a href='".make_link()."'>Index</a>";
$h_next = ($page_number >= $total_pages) ? "Next" : '<a href="'.search_link($search_terms, $next).'">Next</a>';
@ -176,7 +174,7 @@ and of course start organising your images :-)
// only index the first pages of each term
$page->add_html_header('<meta name="robots" content="noindex, nofollow">');
}
$query = url_escape(Tag::caret(Tag::implode($this->search_terms)));
$query = url_escape(Tag::implode($this->search_terms));
$page->add_block(new Block("Posts", $this->build_table($images, "#search=$query"), "main", 10, "image-list"));
$this->display_paginator($page, "post/list/$query", null, $this->page_number, $this->total_pages, true);
} else {

View file

@ -12,7 +12,7 @@ class RSSImages extends Extension
$title = $config->get_string(SetupConfig::TITLE);
if (count($event->search_terms) > 0) {
$search = url_escape(Tag::caret(Tag::implode($event->search_terms)));
$search = url_escape(Tag::implode($event->search_terms));
$page->add_html_header("<link id=\"images\" rel=\"alternate\" type=\"application/rss+xml\" ".
"title=\"$title - Posts with tags: $search\" href=\"".make_link("rss/images/$search/1")."\" />");
} else {

View file

@ -22,11 +22,11 @@ class ViewImage extends Extension
{
global $page, $user;
if ($event->page_matches("post/prev") || $event->page_matches("post/next")) {
if ($event->page_matches("post/prev") || $event->page_matches("post/next")) {
$image_id = int_escape($event->get_arg(0));
if (isset($_GET['search'])) {
$search_terms = Tag::explode(Tag::decaret($_GET['search']));
$search_terms = Tag::explode($_GET['search']);
$query = "#search=".url_escape($_GET['search']);
} else {
$search_terms = [];

View file

@ -45,7 +45,7 @@ class ViewImageTheme extends Themelet
protected function get_query(): ?string
{
if (isset($_GET['search'])) {
$query = "search=".url_escape(Tag::caret($_GET['search']));
$query = "search=".url_escape($_GET['search']);
} else {
$query = null;
}

View file

@ -20,7 +20,7 @@ class CustomIndexTheme extends IndexTheme
$page_title = $config->get_string(SetupConfig::TITLE);
} else {
$search_string = Tag::implode($this->search_terms);
$query = url_escape(Tag::caret($search_string));
$query = url_escape($search_string);
$page_title = html_escape($search_string);
}