Bug 37801: Search results with limits create URLs that cause XML errors in RSS and Atom output

The template for RSS and Atom feeds of search results (curiously named
opac-opensearch.tt) is careful to escape ampersands in the query_cgi param
while adding it to URLs, but doesn't escape the limit_cgi param at all. It
should.

Two drive-by fixes for Atom: because the <title> when your search has a limit
includes &nbsp;, which isn't an XML character entity, you couldn't get as far
as the error from the <link> URL, and as long as I was going to have blame for
the line, I couldn't bear to leave the stray undefined SEARCH_RESULT. in the
(hard-coded and bogus) <link rel="last">.

Test plan:
1. In the OPAC, Advanced search - check the boxes to limit by item type Books
   and Mixed Materials and search for the keyword Perl
2. At the top of the search results, click the orange RSS icon
3. That gives you an ugly "not well-formed" error, so in the URL for the page
   change the final "format=rss" to "format=atom"
4. That gives you an ugly "undefined entity" error, so apply the patch
5. Reload the page with the Atom feed, it should change from an error page
   to a garbled display of the feed. Click Back to go back to the RSS feed
   and reload it if it's still cached on the error page. That should give
   a pretty-printed display of the RSS feed without parsing errors

Sponsored-by: Chetco Community Public Library
Signed-off-by: Sukhmandeep Benipal <sukhmandeep.benipal@inLibro.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
Phil Ringnalda 2024-09-04 20:38:27 -07:00 committed by Katrin Fischer
parent 79464e6224
commit 8298e708b9
Signed by: kfischer
GPG key ID: 0EF6E2C03357A834

View file

@ -39,9 +39,9 @@
<![CDATA[[% LibraryName | html %] Search [% IF ( query_desc ) %]for '[% query_desc | html %]'[% END %][% IF ( limit_desc ) %] with limit(s): '[% limit_desc | html %]'[% END %]]]>
</title>
<link>
[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | $raw %]&#38;sort_by=[% sort_by | uri %]&#38;format=rss
[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]&#38;sort_by=[% sort_by | uri %]&#38;format=rss
</link>
<atom:link rel="self" type="application/rss+xml" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | $raw %]&#38;sort_by=[% sort_by | uri %]&#38;format=rss"/>
<atom:link rel="self" type="application/rss+xml" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]&#38;sort_by=[% sort_by | uri %]&#38;format=rss"/>
<description>
<![CDATA[ Search results [% IF ( query_desc ) %]for '[% query_desc | html %]'[% END %][% IF ( limit_desc ) %] with limit(s): '[% limit_desc | html %]'[% END %] at [% LibraryName | html %]]]>
</description>
@ -52,7 +52,7 @@
[% ELSE %]
<opensearch:itemsPerPage>20</opensearch:itemsPerPage>
[% END %]
<atom:link rel="search" type="application/opensearchdescription+xml" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | $raw %]&#38;sort_by=[% sort_by |uri %]&#38;format=opensearchdescription"/>
<atom:link rel="search" type="application/opensearchdescription+xml" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]&#38;sort_by=[% sort_by |uri %]&#38;format=opensearchdescription"/>
<opensearch:Query role="request" searchTerms="[% query_cgi | uri %][% limit_desc | uri %]" startPage="[% page | html %]" />
[% FOREACH SEARCH_RESULT IN SEARCH_RESULTS %]
<item>
@ -148,8 +148,8 @@
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">
<id>[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | html %][% limit_cgi | html %]&#38;format=atom</id>
<title>[% LibraryName | html %] Search [% IF ( query_desc ) %]for '[% query_desc | html %]'[% END %][% IF ( limit_desc ) %]&nbsp;with limit(s):&nbsp;'[% limit_desc | html %]'[% END %]</title>
<link href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | $raw %]&#38;format=atom"/>
<title>[% LibraryName | html %] Search [% IF ( query_desc ) %]for '[% query_desc | html %]'[% END %][% IF ( limit_desc ) %] with limit(s): '[% limit_desc | html %]'[% END %]</title>
<link href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]&#38;format=atom"/>
<updated>[% timestamp | html %]</updated>
<author>
<name>[% LibraryName | html %]</name>
@ -162,12 +162,12 @@
<opensearch:itemsPerPage>20</opensearch:itemsPerPage>
[% END %]
<opensearch:Query role="request" searchTerms="[% query_desc | uri %] [% limit_desc | uri %]" startPage="[% page | html %]" />
<link rel="alternate" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | $raw %]pw=[% page | uri %]&#38;format=atom" type="application/atom+xml"/>
<link rel="self" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | $raw %]&#38;format=atom" type="application/atom+xml"/>
<link rel="first" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | $raw %]pw=1&#38;format=atom" type="application/atom+xml"/>
<link rel="previous" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | $raw %]pw=2&#38;format=atom" type="application/atom+xml"/>
<link rel="next" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | $raw %]pw=4&#38;format=atom" type="application/atom+xml"/>
<link rel="last" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% SEARCH_RESULT.limit_cgi | $raw %]pw=42299&#38;format=atom" type="application/atom+xml"/>
<link rel="alternate" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]pw=[% page | uri %]&#38;format=atom" type="application/atom+xml"/>
<link rel="self" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]&#38;format=atom" type="application/atom+xml"/>
<link rel="first" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]pw=1&#38;format=atom" type="application/atom+xml"/>
<link rel="previous" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]pw=2&#38;format=atom" type="application/atom+xml"/>
<link rel="next" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]pw=4&#38;format=atom" type="application/atom+xml"/>
<link rel="last" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?[% query_cgi | replace('&', '&#38;') | $raw %][% limit_cgi | replace('&', '&#38;') | $raw %]pw=42299&#38;format=atom" type="application/atom+xml"/>
<link rel="search" type="application/opensearchdescription+xml" href="[% OPACBaseURL | url %]/cgi-bin/koha/opac-search.pl?format=opensearchdescription"/>
[% FOREACH SEARCH_RESULT IN SEARCH_RESULTS %]