From 5fde3ba6d63cd4bafa131b71b843cc23465a5af0 Mon Sep 17 00:00:00 2001 From: Fridolyn SOMERS Date: Tue, 29 Jan 2013 18:03:02 +0100 Subject: [PATCH] Bug 9504: URL escape in OPAC more searches OPACSearchForTitleIn is a syspref used to add links as "more searches" in OPAC record detail page. The links can contain vars depending on record values like title, ISBN, ... Thoses values must be URL-escaped because they can contain special characters that will brake URL and/or HTML. This patch add a method C4::Output::parametrized_url() that replaces vars in URL usign escape and UTF-8 encoding. Test plan : - Define in OPACSearchForTitleIn a link with all possible vars : TITLE, AUTHOR, ISBN, ISSN, CONTROLNUMBER, BIBLIONUMBER - Edit a record to add special characters in title : ", &, ? ... - Go to OPAC detail pages of this record => Check that URL is well encoded => Click on link to check the term is well encoded (diacritical characters, ...) --- C4/Output.pm | 18 ++++++++++++++++-- opac/opac-ISBDdetail.pl | 19 ++++++++++++------- opac/opac-MARCdetail.pl | 19 ++++++++++++------- opac/opac-detail.pl | 17 +++++++++++------ 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/C4/Output.pm b/C4/Output.pm index e1be3e7..6e2c89a 100644 --- a/C4/Output.pm +++ b/C4/Output.pm @@ -28,6 +28,8 @@ package C4::Output; use strict; #use warnings; FIXME - Bug 2505 +use URI::Escape; + use C4::Context; use C4::Dates qw(format_date); use C4::Budgets qw(GetCurrency); @@ -42,13 +44,13 @@ BEGIN { @ISA = qw(Exporter); @EXPORT_OK = qw(&is_ajax ajax_fail); # More stuff should go here instead - %EXPORT_TAGS = ( all =>[qw(setlanguagecookie pagination_bar + %EXPORT_TAGS = ( all =>[qw(setlanguagecookie pagination_bar parametrized_url &output_with_http_headers &output_ajax_with_http_headers &output_html_with_http_headers)], ajax =>[qw(&output_with_http_headers &output_ajax_with_http_headers is_ajax)], html =>[qw(&output_with_http_headers &output_html_with_http_headers)] ); push @EXPORT, qw( - setlanguagecookie getlanguagecookie pagination_bar + setlanguagecookie getlanguagecookie pagination_bar parametrized_url ); push @EXPORT, qw( &output_html_with_http_headers &output_ajax_with_http_headers &output_with_http_headers FormatData FormatNumber @@ -327,6 +329,18 @@ sub is_ajax { return ( $x_req and $x_req =~ /XMLHttpRequest/i ) ? 1 : 0; } +sub parametrized_url { + my $url = shift || ''; # ie page.pl?ln={LANG} + my $vars = shift || {}; # ie { LANG => en } + my $ret = $url; + while ( my ($key,$val) = each %$vars) { + my $val_url = URI::Escape::uri_escape_utf8($val); + $ret =~ s/\{$key\}/$val_url/g; + } + $ret =~ s/\{[^\{]*\}//g; # remove not defined vars + return $ret; +} + END { } # module clean-up code here (global destructor) 1; diff --git a/opac/opac-ISBDdetail.pl b/opac/opac-ISBDdetail.pl index be62879..94055a9 100755 --- a/opac/opac-ISBDdetail.pl +++ b/opac/opac-ISBDdetail.pl @@ -181,15 +181,20 @@ my $marcissns = GetMarcISSN ( $record, $marcflavour ); my $issn = $marcissns->[0] || ''; if (my $search_for_title = C4::Context->preference('OPACSearchForTitleIn')){ - $dat->{author} ? $search_for_title =~ s/{AUTHOR}/$dat->{author}/g : $search_for_title =~ s/{AUTHOR}//g; $dat->{title} =~ s/\/+$//; # remove trailing slash $dat->{title} =~ s/\s+$//; # remove trailing space - $dat->{title} ? $search_for_title =~ s/{TITLE}/$dat->{title}/g : $search_for_title =~ s/{TITLE}//g; - $isbn ? $search_for_title =~ s/{ISBN}/$isbn/g : $search_for_title =~ s/{ISBN}//g; - $issn ? $search_for_title =~ s/{ISSN}/$issn/g : $search_for_title =~ s/{ISSN}//g; - $marccontrolnumber ? $search_for_title =~ s/{CONTROLNUMBER}/$marccontrolnumber/g : $search_for_title =~ s/{CONTROLNUMBER}//g; - $search_for_title =~ s/{BIBLIONUMBER}/$biblionumber/g; - $template->param('OPACSearchForTitleIn' => $search_for_title); + $search_for_title = parametrized_url( + $search_for_title, + { + TITLE => $dat->{title}, + AUTHOR => $dat->{author}, + ISBN => $isbn, + ISSN => $issn, + CONTROLNUMBER => $marccontrolnumber, + BIBLIONUMBER => $biblionumber, + } + ); + $template->param('OPACSearchForTitleIn' => $search_for_title); } output_html_with_http_headers $query, $cookie, $template->output; diff --git a/opac/opac-MARCdetail.pl b/opac/opac-MARCdetail.pl index ac13a9d..2a69244 100755 --- a/opac/opac-MARCdetail.pl +++ b/opac/opac-MARCdetail.pl @@ -296,15 +296,20 @@ my $marcissns = GetMarcISSN( $record, $marcflavour ); my $issn = $marcissns->[0] || ''; if (my $search_for_title = C4::Context->preference('OPACSearchForTitleIn')){ - $dat->{author} ? $search_for_title =~ s/{AUTHOR}/$dat->{author}/g : $search_for_title =~ s/{AUTHOR}//g; $dat->{title} =~ s/\/+$//; # remove trailing slash $dat->{title} =~ s/\s+$//; # remove trailing space - $dat->{title} ? $search_for_title =~ s/{TITLE}/$dat->{title}/g : $search_for_title =~ s/{TITLE}//g; - $isbn ? $search_for_title =~ s/{ISBN}/$isbn/g : $search_for_title =~ s/{ISBN}//g; - $issn ? $search_for_title =~ s/{ISSN}/$issn/g : $search_for_title =~ s/{ISSN}//g; - $marccontrolnumber ? $search_for_title =~ s/{CONTROLNUMBER}/$marccontrolnumber/g : $search_for_title =~ s/{CONTROLNUMBER}//g; - $search_for_title =~ s/{BIBLIONUMBER}/$biblionumber/g; - $template->param('OPACSearchForTitleIn' => $search_for_title); + $search_for_title = parametrized_url( + $search_for_title, + { + TITLE => $dat->{title}, + AUTHOR => $dat->{author}, + ISBN => $isbn, + ISSN => $issn, + CONTROLNUMBER => $marccontrolnumber, + BIBLIONUMBER => $biblionumber, + } + ); + $template->param('OPACSearchForTitleIn' => $search_for_title); } $template->param( diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index 8970090..c04111a 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -966,14 +966,19 @@ my $marcissns = GetMarcISSN ( $record, $marcflavour ); my $issn = $marcissns->[0] || ''; if (my $search_for_title = C4::Context->preference('OPACSearchForTitleIn')){ - $dat->{author} ? $search_for_title =~ s/{AUTHOR}/$dat->{author}/g : $search_for_title =~ s/{AUTHOR}//g; $dat->{title} =~ s/\/+$//; # remove trailing slash $dat->{title} =~ s/\s+$//; # remove trailing space - $dat->{title} ? $search_for_title =~ s/{TITLE}/$dat->{title}/g : $search_for_title =~ s/{TITLE}//g; - $isbn ? $search_for_title =~ s/{ISBN}/$isbn/g : $search_for_title =~ s/{ISBN}//g; - $issn ? $search_for_title =~ s/{ISSN}/$issn/g : $search_for_title =~ s/{ISSN}//g; - $marccontrolnumber ? $search_for_title =~ s/{CONTROLNUMBER}/$marccontrolnumber/g : $search_for_title =~ s/{CONTROLNUMBER}//g; - $search_for_title =~ s/{BIBLIONUMBER}/$biblionumber/g; + $search_for_title = parametrized_url( + $search_for_title, + { + TITLE => $dat->{title}, + AUTHOR => $dat->{author}, + ISBN => $isbn, + ISSN => $issn, + CONTROLNUMBER => $marccontrolnumber, + BIBLIONUMBER => $biblionumber, + } + ); $template->param('OPACSearchForTitleIn' => $search_for_title); } -- 1.7.9.5