diff --git a/Koha/Items.pm b/Koha/Items.pm index 7e0a3e60f1..5e2f405a48 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); @@ -633,22 +634,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 e7406c8f5e..118c9e9fa9 100644 --- a/Koha/SimpleMARC.pm +++ b/Koha/SimpleMARC.pm @@ -18,6 +18,8 @@ package Koha::SimpleMARC; use Modern::Perl; use base 'Exporter'; +use Koha::Regex::Replacement; + BEGIN { our @EXPORT_OK = qw( read_field @@ -717,8 +719,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||; @@ -726,15 +726,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; } } }