Reputation: 6771
I need to replace a whole bunch of PHP super globals in a clients website with a PHP function I made to clean the superglobals from xss attacks.
Here is what the original code might look like:
echo $_REQUEST['HELLO1'] . ' AND ' . $_REQUEST['HELLO2'];
I need it to look like this:
echo MYCLASS::myfunction($_REQUEST['HELLO1']) . ' AND ' . MYCLASS::myfunction($_REQUEST['HELLO2']);
The main issue, I need to do a search/replace on over 100 files! Yikes!
So my solution was this (in linux shell):
sudo sed -i 's/\$_REQUEST[.*\]/MYCLASS::myfunction(&)/g' *.php
This works great as-long-as only one instance of "$_REQUEST" occurs per line... However with multiple instances, it screws up and does this:
echo MYCLASS::myfunction($_REQUEST['HELLO1'] . ' AND ' . $_REQUEST['HELLO2']);
Upvotes: 3
Views: 3270
Reputation: 57774
This should do it:
sed -i "s/\$_REQUEST\[\([^\x5d]*\)\]/MYCLASS::myfunction(\1)/g" *.php
I had a lot of trouble matching ]
, so I've punted with \x5d
.
Upvotes: 0
Reputation: 785256
Try this sed command:
sed -i.bak 's/\$_REQUEST\[\([^]]*\)\]/MYCLASS::myfunction(\1)/g' *.php
or in perl:
perl -pe 's/\$_REQUEST\[([^]]*)\]/MYCLASS::myfunction(\1)/g' file.php
Upvotes: 1
Reputation: 361675
The problem is that .*
is greedy and will find the longest possible match it can. To work around that use [^]]*
instead so that you don't inadvertently grab up an extra set of square brackets.
sudo sed -i 's/\$_REQUEST\[[^]]*\]/MYCLASS::myfunction(&)/g' *.php
In other regex dialects you could also write .*?
to make the wildcard non-greedy, but that doesn't appear to work in sed (at least not in my version, not even with sed -r
).
Upvotes: 2
Reputation: 11
In Perl, the following script will work where you pass the script the name of the file you are interested in
lets say the script is t.pl and your file is file.php
to output back to file.php
perl t.pl file.php > file.php
to output to another file so you don't overwrite your original
perl t.pl file.php > another_file.php
#!/usr/bin/perl
$FILE_NAME = $ARGV[0];
open (FILE_NAME) or die ("Could not open FILE_NAME information file: $FILE_NAME \n");
@file_contents = <FILE_NAME>;
close (FILE_NAME);
foreach $line (@file_contents) {
chomp($line);
$line =~ s/\$_REQUEST\[.*?\]/MYCLASS\:\:myfunction\($&\)/g;
print $line." \n";
}
exit;
Upvotes: 1