RE: Using qr// with substitution and group-interpolation in the substitution part

Claude Brown via beginners <[email protected]> Wed, 25 Oct 2023 21:22:46 +0000
Newsgroups gmane.comp.lang.perl.beginners
Message-ID <SYBP282MB2527E924D9B55E4981AF6269C7DEA@SYBP282MB2527.AUSP282.PROD.OUTLOOK.COM>
I should add that if the script reads values of $regex or $subst from an external source, then my use of eval is seriously flawed.  For example, that external source might provide this value for $subst:

	/; system("do-bad-things"); qr/x/

The eval will execute the "do-bad-things" command on your system.  


-----Original Message-----
From: Claude Brown via beginners <[email protected]> 
Sent: Thursday, October 26, 2023 8:07 AM
To: Levi Elias Nystad-Johansen <[email protected]>; Andrew Solomon <[email protected]>
Cc: Josef Wolf <[email protected]>; [email protected]
Subject: RE: Using qr// with substitution and group-interpolation in the substitution part

CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.

Josef,

Inspired by Levi's “eval” idea, here is my solution:

sub substitute_lines {
    my ($contents, $regex, $subst) = @_;
    eval "\$contents =~ s/$regex/$subst/g";
    return $contents;
}

$data = "foo whatever bar";
$data = &substitute_lines($data, qr/^foo (whatever) bar$/m, 'bar $1 baz');
print "$data\n";

The differences:
- escaped the "$" so the eval gets a literal "$contents"
- didn't escape "$" so the eval receives the value of $regex and $subst
- moved the "g" into the sub as it has no meaning for a qr//
- removed the "m" from the sub as it best left with the original qr//
- added "$data = ..." to get back the value from the subroutine

Cheers,

Claude.