2015-03-17 12 views
5

Piszę skrypt Perla, w którym użytkownik może wprowadzić wyrażenie regularne i ciąg zastępczy. Skrypt przeszuka zestaw plików i zastosuje zmiany według operatora s/// zastosowanego przy wprowadzaniu danych przez użytkownika.Używanie modyfikatora ee bezpiecznie z operatorem s ///, gdy prawa strona jest wprowadzana od użytkownika

Aby nieco komplikować sprawy, zastępczy ciąg może zawierać odwołania od tyłu, aby odnosić się do grup przechwytywania w wyrażeniu regularnym. Na przykład, jeśli wyrażenie regularne to b(.*?)a, a ciąg zastępujący to a$1b, to nie należy traktować go jako dosłownie, ale należy go traktować jako odsyłacz do tyłu, aby przechwycić grupę numer jeden.

W tym ustawieniu zastanawiam się, czy możliwe jest użycie modyfikatora ee (w celu oceny odwołań na wejściu użytkownika) za pomocą operatora s///, gdy prawa strona tego operatora jest wprowadzana przez użytkownika? Na przykład:

use strict; 
use warnings; 
my $str = 'abaaca'; 

my $replacement = 'do{ use Env qw(HOME); unlink "$HOME/important.txt" }'; 

$str =~ s/a(.*?)a/$replacement/gee; 

byłoby niefortunne .. Ale wtedy wpadłem na pomysł, żeby zacytować wejście użytkownika (umieścić go wewnątrz pary podwójnych cudzysłowów) po uszedłszy podwójne cudzysłowy i znak dolara (nie następuje numer), a następniezrobić wymiana:

use feature qw(say); 
use strict; 
use warnings; 

my $str = 'abaaca'; 

my $replacement = shift; 
$replacement =~ s/\"/\\\"/g; 
$replacement =~ s/\$(?!\d)/\\\$/g; 
$replacement = '"' . $replacement . '"'; 
$str =~ s/a(.*?)a/$replacement/gee; 
say $str; 

dla mnie to wydaje się działać na pierwszy rzut oka, czy ja coś przeoczyłem? Na przykład, jeśli skrypt jest nazywany test.pl a użytkownik uruchamia go jako:

$ test.pl 'do{ "a$b" }' 

wyjście jest jako pożądany tylko prosty ciąg (a nie kod jest analizowany):

zrobić { „a $ b "} do {" a $ b "}

Pytanie brzmi: czy to naprawdę jest bezpieczne/prawidłowe podejście?

+0

Jeśli użytkownik po prostu uruchamia skrypt na komputerze, do którego ma już dostęp, dlaczego nie może po prostu edytować go, aby zrobić wszystko, co chciał? Lub, o to chodzi, napisać własny skrypt Perla, który robi złe rzeczy? – ThisSuitIsBlackNot

+0

Jasne, to jest dobra uwaga ... ale myślałem o przypadku, w którym przypadkiem użytkownik wpisał coś, co spowodowało wykonanie kodu w operatorze 's ///'.i to może mieć niepożądane konsekwencje –

Odpowiedz

5

Problem 1:

Nie ma sposobu, aby zastąpić $1 następnie 1 od Następujący tekst zastępuje z ${1}1.

$ script '${1}1' 
${1}1${1}1 

Zadanie 2:

$ script '\${ system "echo rm -rf /" }' 
rm -rf/
Use of uninitialized value in substitution iterator at a.pl line 12. 
rm -rf/
Use of uninitialized value in substitution iterator at a.pl line 12. 

Zadanie 3:

$ script '$1{ system "echo rm -rf /" }' 
rm -rf/
Use of uninitialized value within %1 in string at (eval 1) line 1. 
rm -rf/
Use of uninitialized value within %1 in string at (eval 2) line 1. 

pewnością są inne. Rozwiązanie:

Użyj String::Substitution.

+0

Dzięki, to wygląda dobrze. Wygląda na to, że ktoś już rozwiązał mój problem. –

+0

Jak właściwie działa problem 2? Jeśli wpiszę "skrypt" $ 1 {say ""} "Dostaję błąd" Użycie niezainicjowanej wartości w ciągu% 1 w ciągu znaków na (eval 1) linii 1. 'utknąłem tutaj, dlaczego dostaję ten błąd wiadomość i dlaczego wypowiada "% 1"? –

+0

Może gdybyś wydrukował coś innego niż pusta linia, byłoby bardziej zauważalne, że wydrukowałeś coś ... – ikegami

Powiązane problemy