diff --git a/Koha/AdditionalContents.pm b/Koha/AdditionalContents.pm index a30123d357..765eddb875 100644 --- a/Koha/AdditionalContents.pm +++ b/Koha/AdditionalContents.pm @@ -95,15 +95,23 @@ sub search_for_display { my ( $self, $params ) = @_; my $lang = $params->{lang} || q{}; - # If lang is not default, we will search for entries matching $lang but fallback to default if $lang is not found - # Then we need a subquery count in where clause; DBIx::Class/SQL::Abstract does not support it, fallback to literal SQL - my $subquery = - qq|(SELECT COUNT(*) FROM additional_contents_localizations WHERE lang='$lang' AND additional_content_id=me.additional_content_id)=0|; - my $search_params = get_public_query_search_params($params); $search_params->{lang} = 'default' if !$lang || $lang eq 'default'; - $search_params->{-or} = [ { 'lang' => $lang }, '-and' => [ 'lang', 'default', \$subquery ] ] - if !$search_params->{lang}; + + unless ( $search_params->{lang} ) { + $search_params->{-or} = [ + { lang => $lang }, + { + -and => [ + { lang => 'default' }, + \[ + '(SELECT COUNT(*) FROM additional_contents_localizations WHERE lang = ? AND additional_content_id = me.additional_content_id) = 0', + $lang + ] + ] + } + ]; + } my $attribs = { prefetch => 'additional_content', diff --git a/t/db_dependent/Koha/AdditionalContents.t b/t/db_dependent/Koha/AdditionalContents.t index 6811e480e3..b9cf4fadb5 100755 --- a/t/db_dependent/Koha/AdditionalContents.t +++ b/t/db_dependent/Koha/AdditionalContents.t @@ -192,7 +192,7 @@ subtest '->author' => sub { subtest '->search_for_display' => sub { - plan tests => 4; + plan tests => 5; $schema->storage->txn_begin; @@ -305,6 +305,15 @@ subtest '->search_for_display' => sub { # TODO We should add more tests here $schema->storage->txn_rollback; + + subtest 'prevent SQL injections' => sub { + plan tests => 1; + $schema->storage->txn_begin; + my $lang = q{' OR Booh!}; + Koha::AdditionalContents->search_for_display( { lang => $lang } )->count; + pass(q{Shouldn't get a warning or exception}); + $schema->storage->txn_rollback; + }; }; subtest 'find_best_match' => sub {