diff options
author | Brian Conry <bconry@bestpractical.com> | 2022-06-03 00:12:44 +0300 |
---|---|---|
committer | Brian Conry <bconry@bestpractical.com> | 2022-06-03 00:42:56 +0300 |
commit | 4aa6b5804ea79558c72e9319f78a03d204e3d617 (patch) | |
tree | 4108088405415b8495f19f03bb6db3e1b3539ade | |
parent | feea28f1c0b2cd5db0fa5a2e499959ccbe02ec03 (diff) |
Escape quotes in titles from SavedSearch Dashboard5.0/escape-quotes-savedsearch-dashboard-format-titles
The Saved Searches dashboard creates titles for groups as
"Some Group's saved searches".
This is passed through an HTML escape filter before being embedded in a
string that uses single quotes as the beginning and ending delimiters.
The HTML escapes somewhat handles this, by turning ' into '.
But this broke at some point, believed to be in the 4.2.x range, when
the later HTML scrubbing started turning ' back into '.
This causes /Elements/CollectionAsTable/ParseFormat to receive a
malformed string that it interprets as containing a column delimited by
single quotes followed by a few columns separated by spaces.
Using the example above: "Some Group", "s", "saved", and "searches".
This change adds explicit non-HTML escaping (backslashes, which are
already supported by ParseFormat) of any quotes embedded in the title.
This is done before the HTML entity filtering (which is still
needed).
-rw-r--r-- | lib/RT/Interface/Web.pm | 13 | ||||
-rw-r--r-- | lib/RT/Interface/Web/Handler.pm | 7 | ||||
-rw-r--r-- | share/html/Elements/SavedSearches | 4 |
3 files changed, 20 insertions, 4 deletions
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm index c58ba20758..0592e3e2de 100644 --- a/lib/RT/Interface/Web.pm +++ b/lib/RT/Interface/Web.pm @@ -223,6 +223,19 @@ sub EscapeJS { . "'"; } +=head2 EscapeQuotes SCALAR + +Escapes single and double quotes (U+27 and U+22) with backslashes, and also +escapes backslashes with backslashes. + +=cut + +sub EscapeQuotes { + my $ref = shift; + return unless defined $$ref; + $$ref =~ s/(['"\\])/\\$1/g; +} + =head2 WebCanonicalizeInfo(); Different web servers set different environmental varibles. This diff --git a/lib/RT/Interface/Web/Handler.pm b/lib/RT/Interface/Web/Handler.pm index 9b5a154942..21ab601b34 100644 --- a/lib/RT/Interface/Web/Handler.pm +++ b/lib/RT/Interface/Web/Handler.pm @@ -117,9 +117,10 @@ sub NewHandler { @_ ); - $handler->interp->set_escape( h => \&RT::Interface::Web::EscapeHTML ); - $handler->interp->set_escape( u => \&RT::Interface::Web::EscapeURI ); - $handler->interp->set_escape( j => \&RT::Interface::Web::EscapeJS ); + $handler->interp->set_escape( h => \&RT::Interface::Web::EscapeHTML ); + $handler->interp->set_escape( u => \&RT::Interface::Web::EscapeURI ); + $handler->interp->set_escape( j => \&RT::Interface::Web::EscapeJS ); + $handler->interp->set_escape( q => \&RT::Interface::Web::EscapeQuotes ); if ( !RT->Config->Get('DevelMode') ) { $handler->interp->{rt_mason_cache_created} = RT::Interface::Web::MasonCacheCreatedDate; diff --git a/share/html/Elements/SavedSearches b/share/html/Elements/SavedSearches index 71613a0501..d257e5d3c1 100644 --- a/share/html/Elements/SavedSearches +++ b/share/html/Elements/SavedSearches @@ -55,7 +55,9 @@ % } else { % $title = loc("[_1]'s saved searches",$Object->Name); % } -% $title = $m->interp->apply_escapes($title, 'h'); +% # need to escape both quotes (because we're embedding it in a quote delimited string below) +% # and html entitites (because it will be rendered on a web page) +% $title = $m->interp->apply_escapes($title, 'q', 'h'); <& /Elements/CollectionList, %ARGS, Class => 'RT::SavedSearch', |