From 7f45f31aa82b87384fa09d8a7e8d074c78f703e0 Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:49:51 -0300 Subject: [PATCH 1/8] fix: proper delete posts in a cyclical thread --- post.php | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/post.php b/post.php index 0a0dd94a9..98eb0a068 100644 --- a/post.php +++ b/post.php @@ -185,6 +185,41 @@ function strip_image_metadata(string $img_path): int { return $ret; } +/** + * Delete posts in a cyclical thread. + * + * @param string $boardUri The URI of the board. + * @param int $threadId The ID of the thread. + * @param int $cycleLimit The number of most recent posts to retain. + */ +function delete_cyclical_posts(string $boardUri, int $threadId, int $cycleLimit): void +{ + $query = prepare(sprintf(' + SELECT p.`id` + FROM ``posts_%s`` p + LEFT JOIN ( + SELECT `id` + FROM ``posts_%s`` + WHERE `thread` = :thread + ORDER BY `id` DESC + LIMIT :limit + ) recent_posts ON p.id = recent_posts.id + WHERE p.thread = :thread + AND recent_posts.id IS NULL', + $boardUri, $boardUri + )); + + $query->bindValue(':thread', $threadId, PDO::PARAM_INT); + $query->bindValue(':limit', $cycleLimit, PDO::PARAM_INT); + + $query->execute() or error(db_error($query)); + $ids = $query->fetchAll(PDO::FETCH_COLUMN); + + foreach ($ids as $id) { + deletePost($id, false); + } +} + /** * Method handling functions */ @@ -1282,11 +1317,7 @@ function ipv4to6($ip) { // Handle cyclical threads if (!$post['op'] && isset($thread['cycle']) && $thread['cycle']) { - // Query is a bit weird due to "This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'" (MariaDB Ver 15.1 Distrib 10.0.17-MariaDB, for Linux (x86_64)) - $query = prepare(sprintf('DELETE FROM ``posts_%s`` WHERE `thread` = :thread AND `id` NOT IN (SELECT `id` FROM (SELECT `id` FROM ``posts_%s`` WHERE `thread` = :thread ORDER BY `id` DESC LIMIT :limit) i)', $board['uri'], $board['uri'])); - $query->bindValue(':thread', $post['thread']); - $query->bindValue(':limit', $config['cycle_limit'], PDO::PARAM_INT); - $query->execute() or error(db_error($query)); + delete_cyclical_posts($board['uri'], $post['thread'], $config['cycle_limit']); } if (isset($post['antispam_hash'])) { From 9f5efdddbe27f91a59fa9bf6f80c2fde09f2385a Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:33:48 -0300 Subject: [PATCH 2/8] remove inline highlightReply --- inc/display.php | 34 +++++++++++++++--------- inc/functions.php | 42 +++++++++++++++++++++--------- js/show-backlinks.js | 2 +- templates/main.js | 53 +++++++++++++++++++++++++------------- templates/post_reply.html | 2 +- templates/post_thread.html | 2 +- 6 files changed, 90 insertions(+), 45 deletions(-) diff --git a/inc/display.php b/inc/display.php index 1d74424f2..d7ea01961 100644 --- a/inc/display.php +++ b/inc/display.php @@ -376,14 +376,19 @@ public function __construct($post, $root=null, $mod=false) { markup($this->body); } - if ($this->mod) + if ($this->mod) { // Fix internal links // Very complicated regex - $this->body = preg_replace( - '/body + ); + } } public function link($pre = '', $page = false) { global $config, $board; @@ -431,14 +436,19 @@ public function __construct($post, $root = null, $mod = false, $hr = true) { markup($this->body); } - if ($this->mod) + if ($this->mod) { // Fix internal links // Very complicated regex - $this->body = preg_replace( - '/body + ); + } } public function link($pre = '', $page = false) { global $config, $board; diff --git a/inc/functions.php b/inc/functions.php index 2f23ef090..ee93ce99c 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -2128,11 +2128,19 @@ function markup(&$body, $track_cites = false, $op = false) { } if (isset($cited_posts[$cite])) { - $replacement = '' . - '>>' . $cite . - ''; + $classAttribute = 'class="highlight-link"'; + $dataCiteAttribute = 'data-cite="' . htmlspecialchars($cite, ENT_QUOTES, 'UTF-8') . '"'; + $hrefValue = $config['root'] . $board['dir'] . $config['dir']['res'] + . link_for(['id' => $cite, 'thread' => $cited_posts[$cite]]) + . '#' . $cite; + $linkText = '>>' . htmlspecialchars($cite, ENT_QUOTES, 'UTF-8'); + + $replacement = $matches[1][0] . '' + . $linkText + . ''; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen($matches[0][0]); @@ -2224,13 +2232,23 @@ function markup(&$body, $track_cites = false, $op = false) { if ($cite) { if (isset($cited_posts[$_board][$cite])) { $link = $cited_posts[$_board][$cite]; - - $replacement = '' . - '>>>/' . $_board . '/' . $cite . - ''; + $classAttribute = ''; + if ($_board == $board['uri']) { + $classAttribute = 'class="highlight-link" data-cite="' . htmlspecialchars($cite, ENT_QUOTES, 'UTF-8') . '"'; + } + + $hrefValue = htmlspecialchars($link, ENT_QUOTES, 'UTF-8'); + + $linkText = '>>>/' + . htmlspecialchars($_board, ENT_QUOTES, 'UTF-8') + . '/' . htmlspecialchars($cite, ENT_QUOTES, 'UTF-8'); + + $replacement = $matches[1][0] + . '' + . $linkText + . ''; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); diff --git a/js/show-backlinks.js b/js/show-backlinks.js index fc3125db4..93c7d47a4 100644 --- a/js/show-backlinks.js +++ b/js/show-backlinks.js @@ -39,7 +39,7 @@ onready(function(){ if ($mentioned.find('a.mentioned-' + reply_id).length != 0) return; - var $link = $('>>' + + var $link = $('>>' + reply_id + ''); $link.appendTo($mentioned) diff --git a/templates/main.js b/templates/main.js index 3b32f916c..f3a7b2c66 100644 --- a/templates/main.js +++ b/templates/main.js @@ -220,24 +220,23 @@ function get_cookie(cookie_name) { return null; } -function highlightReply(id) { - if (typeof window.event != "undefined" && event.which == 2) { - // don't highlight on middle click - return true; - } - - var divs = document.getElementsByTagName('div'); - for (var i = 0; i < divs.length; i++) - { - if (divs[i].className.indexOf('post') != -1) - divs[i].className = divs[i].className.replace(/highlighted/, ''); - } - if (id) { - var post = document.getElementById('reply_'+id); - if (post) - post.className += ' highlighted'; - window.location.hash = id; - } +function highlightReply(id, evt) { + if (evt && evt.button === 1) { + return true; + } + + document.querySelectorAll('div.post').forEach(div => { + div.classList.remove('highlighted'); + }); + + if (id) { + const post = document.getElementById(`reply_${id}`); + if (post) { + post.classList.add('highlighted'); + window.location.hash = id; + } + } + return true; } @@ -386,6 +385,24 @@ function ready() { } } +function addLinkListenersCite(selector, callback) { + document.querySelector('body').addEventListener('click', (event) => { + if (event.target.matches(selector)) { + event.preventDefault(); + + var cite = event.target.getAttribute('data-cite'); + + if (callback(cite, event)) { + window.location.href = event.target.href; + } + } + }); +} + +document.addEventListener('DOMContentLoaded', () => { + addLinkListenersCite('.highlight-link', highlightReply); +}); + {% endverbatim %} var post_date = "{{ config.post_date }}"; diff --git a/templates/post_reply.html b/templates/post_reply.html index e6f5fa09f..639ee880b 100644 --- a/templates/post_reply.html +++ b/templates/post_reply.html @@ -14,7 +14,7 @@ {% apply spaceless %} {% include 'post/poster_id.html' %}  - No. + No. {{ post.id }}

{% endapply %} diff --git a/templates/post_thread.html b/templates/post_thread.html index e9c5cc128..6458a733a 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -18,7 +18,7 @@ {% apply spaceless %} {% include 'post/poster_id.html' %}  - No. + No. {{ post.id }} {% if post.sticky %} {% if config.font_awesome %} From 36de809c9046493f73472590788dad1ae3420ecf Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:41:59 -0300 Subject: [PATCH 3/8] remove citeReply inline --- templates/main.js | 40 +++++++++++++++------------- templates/post_reply.html | 2 +- templates/post_thread.html | 2 +- templates/post_thread_fileboard.html | 2 +- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/templates/main.js b/templates/main.js index f3a7b2c66..5dc5ac793 100644 --- a/templates/main.js +++ b/templates/main.js @@ -268,26 +268,27 @@ function dopost(form) { } function citeReply(id, with_link) { - var textarea = document.getElementById('body'); + var textarea = document.getElementById('body'); + + if (!textarea) return false; + + var insertionText = '>>' + id + '\n'; + + if (document.selection) { + // IE + textarea.focus(); + var sel = document.selection.createRange(); + sel.text = insertionText; + } else if (textarea.selectionStart !== undefined) { + var start = textarea.selectionStart; + var end = textarea.selectionEnd; + textarea.value = textarea.value.substring(0, start) + insertionText + textarea.value.substring(end); + + textarea.selectionStart = textarea.selectionEnd = start + insertionText.length; + } else { + textarea.value += insertionText; + } - if (!textarea) return false; - - if (document.selection) { - // IE - textarea.focus(); - var sel = document.selection.createRange(); - sel.text = '>>' + id + '\n'; - } else if (textarea.selectionStart || textarea.selectionStart == '0') { - var start = textarea.selectionStart; - var end = textarea.selectionEnd; - textarea.value = textarea.value.substring(0, start) + '>>' + id + '\n' + textarea.value.substring(end, textarea.value.length); - - textarea.selectionStart += ('>>' + id).length + 1; - textarea.selectionEnd = textarea.selectionStart; - } else { - // ??? - textarea.value += '>>' + id + '\n'; - } if (typeof $ != 'undefined') { var select = document.getSelection().toString(); if (select) { @@ -401,6 +402,7 @@ function addLinkListenersCite(selector, callback) { document.addEventListener('DOMContentLoaded', () => { addLinkListenersCite('.highlight-link', highlightReply); + addLinkListenersCite('.cite-link', citeReply); }); {% endverbatim %} diff --git a/templates/post_reply.html b/templates/post_reply.html index 639ee880b..a9006d090 100644 --- a/templates/post_reply.html +++ b/templates/post_reply.html @@ -15,7 +15,7 @@ {% apply spaceless %} {% include 'post/poster_id.html' %}  No. - {{ post.id }} + {{ post.id }}

{% endapply %} {% include 'post/fileinfo.html' %} diff --git a/templates/post_thread.html b/templates/post_thread.html index 6458a733a..75bfdcafb 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -19,7 +19,7 @@ {% apply spaceless %} {% include 'post/poster_id.html' %}  No. - {{ post.id }} + {{ post.id }} {% if post.sticky %} {% if config.font_awesome %} diff --git a/templates/post_thread_fileboard.html b/templates/post_thread_fileboard.html index 1b71766a3..9ddb9924d 100644 --- a/templates/post_thread_fileboard.html +++ b/templates/post_thread_fileboard.html @@ -5,7 +5,7 @@ -{{ post.id }} +{{ post.id }} {% include 'post/name.html' %} {% include 'post/flag.html' %} [{{ post.files[0].filename|e|bidi_cleanup }}] From 5aa8fe74aa4ba98ee36200733917b4d94c77b1bf Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:45:00 -0300 Subject: [PATCH 4/8] remove post-form inline javascript --- templates/main.js | 13 +++++++++++++ templates/post_form.html | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/templates/main.js b/templates/main.js index 5dc5ac793..46bad505f 100644 --- a/templates/main.js +++ b/templates/main.js @@ -400,9 +400,22 @@ function addLinkListenersCite(selector, callback) { }); } +function addFormListener() { + var form = document.getElementById('post-form'); + + if (form) { + form.addEventListener('submit', function(event) { + if (!dopost(form)) { + event.preventDefault(); + } + }); + } +} + document.addEventListener('DOMContentLoaded', () => { addLinkListenersCite('.highlight-link', highlightReply); addLinkListenersCite('.cite-link', citeReply); + addFormListener(); }); {% endverbatim %} diff --git a/templates/post_form.html b/templates/post_form.html index b70f2f547..f179b9939 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -1,4 +1,4 @@ -
+ {{ antibot.html() }} {% if id %}{% endif %} {{ antibot.html() }} From f3cb1e56d5f3bcad9ff6eea1c31ab6695ff090d4 Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:52:22 -0300 Subject: [PATCH 5/8] remove ready() calls from template --- templates/generic_page.html | 3 --- templates/index.html | 4 ---- templates/main.js | 6 +++++- templates/post_form.html | 6 +----- templates/themes/catalog/catalog.html | 11 ----------- templates/thread.html | 4 ---- 6 files changed, 6 insertions(+), 28 deletions(-) diff --git a/templates/generic_page.html b/templates/generic_page.html index ce06a6b1f..83451ff09 100644 --- a/templates/generic_page.html +++ b/templates/generic_page.html @@ -36,8 +36,5 @@

{{ board.url }} - {{ board.name }}

{% endfor %} {{ btn.next }} {{ boardlist.bottom }} {% include 'footer.html' %} - diff --git a/templates/index.html b/templates/index.html index 118ddbccb..11faea67a 100644 --- a/templates/index.html +++ b/templates/index.html @@ -89,9 +89,5 @@

{{ board.url }} - {{ board.title|e }}

{{ config.ad.bottom }} {% include 'footer.html' %} - - diff --git a/templates/main.js b/templates/main.js index 46bad505f..1721d7017 100644 --- a/templates/main.js +++ b/templates/main.js @@ -357,7 +357,9 @@ var script_settings = function(script_name) { }; function init() { - init_stylechooser(); + if (active_page !== 'page') { + init_stylechooser(); + } {% endverbatim %} {% if config.allow_delete %} @@ -413,6 +415,8 @@ function addFormListener() { } document.addEventListener('DOMContentLoaded', () => { + ready(); + rememberStuff(); addLinkListenersCite('.highlight-link', highlightReply); addLinkListenersCite('.cite-link', citeReply); addFormListener(); diff --git a/templates/post_form.html b/templates/post_form.html index f179b9939..bdaa210b8 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -228,8 +228,4 @@ {{ antibot.html(true) }} -
- - + \ No newline at end of file diff --git a/templates/themes/catalog/catalog.html b/templates/themes/catalog/catalog.html index 342029078..1fc4cdc4a 100644 --- a/templates/themes/catalog/catalog.html +++ b/templates/themes/catalog/catalog.html @@ -75,17 +75,6 @@

{{ settings.title }} (/{{ board }}/)


{% include 'footer.html' %} - - - {% endapply %} diff --git a/templates/thread.html b/templates/thread.html index 89eda7b0d..ea49acf8e 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -83,9 +83,5 @@

{{ board.url }} - {{ board.title|e }}

{{ config.ad.bottom }} {% include 'footer.html' %} - - From 1edaf6716795b7de1f27d58a6f6114a26407004a Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Wed, 14 Aug 2024 12:12:17 -0300 Subject: [PATCH 6/8] remove inline javascript from ukko --- templates/themes/ukko/theme.php | 2 +- templates/themes/ukko/ukko.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/themes/ukko/theme.php b/templates/themes/ukko/theme.php index b0a49131d..5e263ac88 100644 --- a/templates/themes/ukko/theme.php +++ b/templates/themes/ukko/theme.php @@ -98,7 +98,7 @@ public function build($mod = false) { $count += 1; } - $body .= ''; + $body .= ''; $body .= ''; return Element('index.html', array( diff --git a/templates/themes/ukko/ukko.js b/templates/themes/ukko/ukko.js index b2668e0bf..7aa33811b 100644 --- a/templates/themes/ukko/ukko.js +++ b/templates/themes/ukko/ukko.js @@ -54,6 +54,7 @@ $(document).ready(function() { $('.pages').hide(); var loadnext = function() { + let overflow = JSON.parse(document.getElementById('overflow-data').textContent || '[]'); if (overflow.length == 0) { $('.pages').show().html(_("No more threads to display")); } From 6c39c474fc495668a546a1c195e989f5e53ce320 Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Wed, 14 Aug 2024 12:21:50 -0300 Subject: [PATCH 7/8] remove secure_link_confirm inline javascript --- inc/display.php | 9 +++++++-- inc/template.php | 12 ++---------- js/mod/mod-scripts.js | 18 ++++++++++++++++++ templates/header.html | 3 +++ 4 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 js/mod/mod-scripts.js diff --git a/inc/display.php b/inc/display.php index d7ea01961..8b174ded3 100644 --- a/inc/display.php +++ b/inc/display.php @@ -307,10 +307,15 @@ function bidi_cleanup($data) { } function secure_link_confirm($text, $title, $confirm_message, $href) { - global $config; + $secure_url = htmlspecialchars('?/' . $href . '/' . make_secure_link_token($href), ENT_QUOTES, 'UTF-8'); + + $title = htmlentities($title); - return '' . $text . ''; + $confirm_message = htmlentities($confirm_message); + + return "{$text}"; } + function secure_link($href) { return $href . '/' . make_secure_link_token($href); } diff --git a/inc/template.php b/inc/template.php index 0362111c4..f3a99feae 100644 --- a/inc/template.php +++ b/inc/template.php @@ -117,8 +117,8 @@ public function getFunctions() new Twig\TwigFunction('hiddenInputs', 'hiddenInputs'), new Twig\TwigFunction('hiddenInputsHash', 'hiddenInputsHash'), new Twig\TwigFunction('ratio', 'twig_ratio_function'), - new Twig\TwigFunction('secure_link_confirm', 'twig_secure_link_confirm'), - new Twig\TwigFunction('secure_link', 'twig_secure_link'), + new Twig\TwigFunction('secure_link_confirm', 'secure_link_confirm'), + new Twig\TwigFunction('secure_link', 'secure_link'), new Twig\TwigFunction('link_for', 'link_for') ); } @@ -193,11 +193,3 @@ function twig_filename_truncate_filter($value, $length = 30, $separator = '…') function twig_ratio_function($w, $h) { return fraction($w, $h, ':'); } -function twig_secure_link_confirm($text, $title, $confirm_message, $href) { - global $config; - - return '' . $text . ''; -} -function twig_secure_link($href) { - return $href . '/' . make_secure_link_token($href); -} diff --git a/js/mod/mod-scripts.js b/js/mod/mod-scripts.js new file mode 100644 index 000000000..5e1976d7c --- /dev/null +++ b/js/mod/mod-scripts.js @@ -0,0 +1,18 @@ +function addSecureLinkListener() { + document.addEventListener('click', function(event) { + var link = event.target.closest('a[data-href]'); + if (link) { + if (event.button === 1) return; + + event.preventDefault(); + + var confirmMessage = link.getAttribute('data-confirm'); + if (confirm(confirmMessage)) { + window.location.href = link.getAttribute('data-href'); + } + } + }); +} +document.addEventListener("DOMContentLoaded", function() { + addSecureLinkListener(); +}); \ No newline at end of file diff --git a/templates/header.html b/templates/header.html index d35fabb97..c020eaff0 100644 --- a/templates/header.html +++ b/templates/header.html @@ -11,6 +11,9 @@ var inMod = {% if mod %}true{% else %}false{% endif %}; var modRoot="{{ config.root }}"+(inMod ? "mod.php?/" : ""); + {% if mod %} + + {% endif %} {% if not nojavascript %} {% if not config.additional_javascript_compile %} From 3ff4d1c896fb0c63da1d81fcdc2c8e1d656ab497 Mon Sep 17 00:00:00 2001 From: Weav <89118232+perdedora@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:42:26 +0000 Subject: [PATCH 8/8] Use shorthand in addFormListener --- templates/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/main.js b/templates/main.js index a9459b21f..bf0860f3a 100644 --- a/templates/main.js +++ b/templates/main.js @@ -413,7 +413,7 @@ function addFormListener() { var form = document.getElementById('post-form'); if (form) { - form.addEventListener('submit', function(event) { + form.addEventListener('submit', (event) => { if (!dopost(form)) { event.preventDefault(); }