* patch by avk959 to solve infinite loop in FindMatchesBoyerMoore*, resolves #39885 and #39709

+ tests
This commit is contained in:
florian 2022-10-17 21:14:32 +02:00
parent 5670a7543c
commit e457cdad8a
3 changed files with 53 additions and 2 deletions

View File

@ -440,7 +440,7 @@ begin
AddMatch(i+1);
//Only first match ?
if not aMatchAll then break;
inc(i,DeltaJumpTable2[0]);
inc(i,DeltaJumpTable2[0]+1);
end else begin
i:=i + Max(DeltaJumpTable1[ord(s[i])],DeltaJumpTable2[j]);
end;
@ -592,7 +592,7 @@ begin
AddMatch(i+1);
//Only first match ?
if not aMatchAll then break;
inc(i,DeltaJumpTable2[0]);
inc(i,DeltaJumpTable2[0]+1);
end else begin
i:=i + Max(DeltaJumpTable1[Ord(lCaseArray[Ord(s[i])])],DeltaJumpTable2[j]);
end;

26
tests/webtbs/tw39709.pp Normal file
View File

@ -0,0 +1,26 @@
{$mode delphi}
uses
SysUtils, StrUtils;
procedure Test(const s, find, repl, expect: string; flags: TReplaceFlags; algo: TStringReplaceAlgorithm);
begin
write((s + ',').PadRight(27), ' ', find.PadRight(5), ' -> ', (repl + IfThen(rfIgnoreCase in flags, ' [I]') + ':').PadRight(12), ' ');
writeln(StrUtils.StringReplace(s, find, repl, flags, algo));
if StrUtils.StringReplace(s, find, repl, flags, algo)<>expect then
halt(1);
end;
var
algo: TStringReplaceAlgorithm;
begin
for algo in TStringReplaceAlgorithm do
begin
writeln(algo);
Test('This works', 'works', 'only works', 'This only works', [rfReplaceAll], algo);
Test('Hello World', 'hello', 'goodbye', 'goodbye World', [rfReplaceAll, rfIgnoreCase], algo);
Test('ababab', 'a', 'z', 'zbzbzb', [rfReplaceAll], algo);
Test('Nani wo nasu tame umareta?', 'a', '-', 'N-ni wo n-su t-me um-ret-?', [rfReplaceAll], algo);
writeln;
end;
end.

25
tests/webtbs/tw39885.pp Normal file
View File

@ -0,0 +1,25 @@
uses
strutils;
Var
matches: SizeIntArray;
i : Longint;
begin
FindMatchesBoyerMooreCaseSensitive('a x b x c', 'x', matches, {matchAll}true); // never returns
if matches[0]<>3 then
halt(1);
if matches[1]<>7 then
halt(1);
FindMatchesBoyerMooreCaseSensitive('a xx b xx c', 'xx', matches, {matchAll}true); // never returns
if matches[0]<>3 then
halt(1);
if matches[1]<>8 then
halt(1);
FindMatchesBoyerMooreCaseSensitive('a xy b xy c', 'xy', matches, {matchAll}true); // ok
if matches[0]<>3 then
halt(1);
if matches[1]<>8 then
halt(1);
writeln('ok');
end.