Thread Zeitbegrenzung für reguläre Ausdrücke (40 answers)
Opened by Crian at 2005-04-25 13:24

Taulmarill
 2005-04-26 16:51
#54181 #54181
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
ich glaub ich hab was gutes gefunden :-)
der trick ist, in den regex möglicht performanten perlcode einzubetten, damit mehrere opcodes ausgeführt werden, dann greift alarm auch wieder. ich hab einfach mal die koknstante 1 benutzt, was trivialeres fiel mir auf die schnelle nicht ein.
der alarm greift hier sobald der eingebettete perlcode nach der alarmzeit ausgeführt wird, 'ne verzögerung von ein paar sekunden ist also drin. evtl. lässt sich das noch tunen indem man das im regex verschiebt bzw. an weiteren stellen platziert. performancemässig macht das <1% aus.
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
use strict;
use warnings;

use Time::HiRes qw(time);
use constant TIMEOUT => 1;

my $bigString = pack "C*", 33 .. 126;
$bigString = $bigString x 1_000_000;
my $time_to_die = time + TIMEOUT;

eval {
local $SIG{ALRM} = sub { die "regex timed out at ", time, "\n" };
alarm TIMEOUT;

print "time to die at $time_to_die\n";
print "begin regex at ", time, "\n";
my ( $foo, $bar, $baz ) = $bigString =~ /(?{1})(abc).*(def).*(ghi)/;
print "foo = $foo, bar = $bar, baz = $baz\n";
print "end regex at ", time, "\n";

alarm 0;
};

print "error while regex. $@\n" if $@;

use Benchmark qw(:all);

cmpthese ( 5, {
'mit ' => sub { $bigString =~ /(?{1})(abc).*(def).*(ghi)/ },
'ohne ' => sub { $bigString =~ /(abc).*(def).*(ghi)/ }
} );
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B

View full thread Zeitbegrenzung für reguläre Ausdrücke