diff --git a/Koha/Items.pm b/Koha/Items.pm index 862631fbfb..d7448b8e31 100644 --- a/Koha/Items.pm +++ b/Koha/Items.pm @@ -32,6 +32,7 @@ use Koha::SearchEngine::Indexer; use Koha::Item::Attributes; use Koha::Item; use Koha::CirculationRules; +use Koha::Regex::Replacement; use base qw(Koha::Objects); @@ -630,22 +631,24 @@ sub apply_regex { my $modifiers = $params->{modifiers} || q{}; my $value = $params->{value}; - $replace =~ s/"/\\"/g; # Protection from embedded code - $replace = '"' . $replace . '"'; # Put in a string for /ee my @available_modifiers = qw( i g ); my $retained_modifiers = q||; for my $modifier ( split //, $modifiers ) { $retained_modifiers .= $modifier if grep { /$modifier/ } @available_modifiers; } + + # The replacement is expanded as DATA (capture-group backreferences and the + # \n \r \t escapes) and never evaluated as code, so @{...}/${...} + # interpolation blocks are inert text, not Perl. if ( $retained_modifiers =~ m/^(ig|gi)$/ ) { - $value =~ s/$search/$replace/igee; + $value =~ s/$search/Koha::Regex::Replacement::expand_template( $replace, [@{^CAPTURE}], {%+} )/ige; } elsif ( $retained_modifiers eq 'i' ) { - $value =~ s/$search/$replace/iee; + $value =~ s/$search/Koha::Regex::Replacement::expand_template( $replace, [@{^CAPTURE}], {%+} )/ie; } elsif ( $retained_modifiers eq 'g' ) { - $value =~ s/$search/$replace/gee; + $value =~ s/$search/Koha::Regex::Replacement::expand_template( $replace, [@{^CAPTURE}], {%+} )/ge; } else { - $value =~ s/$search/$replace/ee; + $value =~ s/$search/Koha::Regex::Replacement::expand_template( $replace, [@{^CAPTURE}], {%+} )/e; } return $value; diff --git a/Koha/SimpleMARC.pm b/Koha/SimpleMARC.pm index 1b188e7b98..07029a5c91 100644 --- a/Koha/SimpleMARC.pm +++ b/Koha/SimpleMARC.pm @@ -21,6 +21,9 @@ use constant LAST_TRANSACTION_FIELD => q/005/; # MARC21/UNIMARC our ( @ISA, @EXPORT_OK ); +use Koha::Exceptions; +use Koha::Regex::Replacement; + BEGIN { require Exporter; our @ISA = qw(Exporter); @@ -721,8 +724,6 @@ sub _modify_values { if ( $regex and $regex->{search} ) { my $replace = $regex->{replace}; - $replace =~ s/"/\\"/g; # Protection from embedded code - $replace = '"' . $replace . '"'; # Put in a string for /ee $regex->{modifiers} //= q||; my @available_modifiers = qw( i g ); my $modifiers = q||; @@ -730,15 +731,20 @@ sub _modify_values { $modifiers .= $modifier if grep { /$modifier/ } @available_modifiers; } + my $search = $regex->{search}; foreach my $value (@$values) { + + # The replacement is expanded as DATA (capture-group backreferences + # and the \n \r \t escapes) and never evaluated as code, so + # @{...}/${...} interpolation blocks are inert text, not Perl. if ( $modifiers =~ m/^(ig|gi)$/ ) { - $value =~ s/$regex->{search}/$replace/igee; + $value =~ s/$search/Koha::Regex::Replacement::expand_template( $replace, [@{^CAPTURE}], {%+} )/ige; } elsif ( $modifiers eq 'i' ) { - $value =~ s/$regex->{search}/$replace/iee; + $value =~ s/$search/Koha::Regex::Replacement::expand_template( $replace, [@{^CAPTURE}], {%+} )/ie; } elsif ( $modifiers eq 'g' ) { - $value =~ s/$regex->{search}/$replace/gee; + $value =~ s/$search/Koha::Regex::Replacement::expand_template( $replace, [@{^CAPTURE}], {%+} )/ge; } else { - $value =~ s/$regex->{search}/$replace/ee; + $value =~ s/$search/Koha::Regex::Replacement::expand_template( $replace, [@{^CAPTURE}], {%+} )/e; } } }