From 02af9435e633bfad04b8b0d89498b330935a8175 Mon Sep 17 00:00:00 2001
From: Julian Maurice <julian.maurice@biblibre.com>
Date: Fri, 8 Jan 2021 10:58:45 +0100
Subject: [PATCH] Bug 27336: (alternative) Sanitize correctly HTML id
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Valid characters are alphanumeric characters (a-zA-Z0-9), hyphen (-)
and underscore (_)

https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier

All invalid characters will be replaced by '_'

Test plan:
1. Go to Administration ยป System preferences and click on 'Searching'
   tab
2. You should see a console error (Uncaught Error: Syntax error,
   unrecognized expression: #collapse_Did_you_mean/spell_checking)
3. Apply patch
4. Make sure the error is gone
5. prove t/Koha_Template_Plugin_HtmlId.t

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
---
 Koha/Template/Plugin/HtmlId.pm                     | 28 ++++++++++++++++++++++
 .../intranet-tmpl/prog/en/includes/prefs-menu.inc  |  3 ++-
 .../prog/en/modules/admin/preferences.tt           |  7 +++---
 t/Koha_Template_Plugin_HtmlId.t                    | 25 +++++++++++++++++++
 4 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 Koha/Template/Plugin/HtmlId.pm
 create mode 100755 t/Koha_Template_Plugin_HtmlId.t

diff --git a/Koha/Template/Plugin/HtmlId.pm b/Koha/Template/Plugin/HtmlId.pm
new file mode 100644
index 0000000000..13fc9e8500
--- /dev/null
+++ b/Koha/Template/Plugin/HtmlId.pm
@@ -0,0 +1,28 @@
+package Koha::Template::Plugin::HtmlId;
+
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use parent qw( Template::Plugin::Filter );
+
+sub filter {
+    my ( $self, $text ) = @_;
+
+    return $text =~ s/[^a-zA-Z0-9-]+/_/gr
+}
+
+1;
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/prefs-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/prefs-menu.inc
index 7024bd0ae2..055069e75c 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/prefs-menu.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/prefs-menu.inc
@@ -1,3 +1,4 @@
+[% USE HtmlId %]
 <div id="menu">
     <ul>
         [% IF ( accounting ) %]
@@ -176,7 +177,7 @@
             <ul>
                 [% FOREACH LINE IN TAB.LINES %]
                     [% IF ( LINE.is_group_title ) %]
-                        <li><a class="pref_sublink" href="#[% LINE.title | replace('\s+', '_') | uri %]">[% LINE.title | html %]</a></li>
+                        <li><a class="pref_sublink" href="#[% LINE.title | $HtmlId %]">[% LINE.title | html %]</a></li>
                     [% END %]
                 [% END %]
             </ul>
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences.tt
index 977a7834fe..54dfe5f951 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences.tt
@@ -2,6 +2,7 @@
 [% USE To %]
 [% USE Asset %]
 [% USE Koha %]
+[% USE HtmlId %]
 [% SET footerjs = 1 %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; Administration &rsaquo; System preferences</title>
@@ -49,16 +50,16 @@
             [% UNLESS ( loop.first ) %]</tbody></table>[% END %]
             <div class="row">
                 <div class="col-sm-6">
-                    <h3 id="[% LINE.title | replace('\s+', '_') | html %]"><i class="fa fa-caret-down"></i> [% LINE.title | html %]</h3>
+                    <h3 id="[% LINE.title | $HtmlId %]"><i class="fa fa-caret-down"></i> [% LINE.title | html %]</h3>
                 </div>
                 <div class="col-sm-6">
                     [% IF ( searchfield ) %]
-                        <div class="pull-right"><a class="btn btn-link" href="/cgi-bin/koha/admin/preferences.pl?tab=[% TAB.tab_id | html %]#[% LINE.title | replace('\s+', '_') | html %]"><i class="fa fa-list-ul"></i> View all [% LINE.title | html %] preferences</a></div>
+                        <div class="pull-right"><a class="btn btn-link" href="/cgi-bin/koha/admin/preferences.pl?tab=[% TAB.tab_id | html %]#[% LINE.title | $HtmlId %]"><i class="fa fa-list-ul"></i> View all [% LINE.title | html %] preferences</a></div>
                     [% END %]
                 </div>
             </div>
 
-            <table class="preferences" id="collapse_[% LINE.title | replace('\s+', '_') | html %]">
+            <table class="preferences" id="collapse_[% LINE.title | $HtmlId %]">
             <thead><tr><th>Preference</th><th>Value</th></tr></thead>
             [% UNLESS ( loop.last ) %]<tbody>[% END %]
             [% ELSE %]
diff --git a/t/Koha_Template_Plugin_HtmlId.t b/t/Koha_Template_Plugin_HtmlId.t
new file mode 100755
index 0000000000..7e767a2cc9
--- /dev/null
+++ b/t/Koha_Template_Plugin_HtmlId.t
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Test::More tests => 2;
+
+use_ok( 'Koha::Template::Plugin::HtmlId' );
+
+my $filter = Koha::Template::Plugin::HtmlId->new();
+is('Some_not-allowed_characters', $filter->filter('Some/;:not-allowed*$^characters'), 'Forbidden characters are replaced by _');
-- 
2.11.0