BeRo1985 / flre

FLRE - Fast Light Regular Expressions - A fast light regular expression library
GNU Lesser General Public License v2.1
94 stars 23 forks source link

Look ahead and look behind are broken #42

Closed pyscripter closed 6 years ago

pyscripter commented 6 years ago

Try the following:

  FLREInstance:=TFLRE.Create('(?<=abc)def',[]);
   Writeln(FLREInstance.Find('abcdef'));
  FLREInstance:=TFLRE.Create('(?<!abc)def',[]);
   Writeln(FLREInstance.Find('abcdef'));
   FLREInstance:=TFLRE.Create('abc(?!def)',[]);
   Writeln(FLREInstance.Find('abcdef'));
   FLREInstance:=TFLRE.Create('abc(?=def)',[]);
   Writeln(FLREInstance.Find('abcdef'));

The problem lies in TFLREThreadLocalStorageInstance.LookAssertion. Below is the fixed function. With the fix look ahead and behind positive or negative work fine. The two changes (index adjustement) are marked with a comment.

function TFLREThreadLocalStorageInstance.LookAssertion(const Position,WhichLookAssertionString:TFLREInt32;const LookBehind,Negative:boolean):boolean;
var Index,LookAssertionStringLength,BasePosition:TFLREInt32;
    LookAssertionString:TFLRERawByteString;
begin
 if WhichLookAssertionString<Instance.CountLookAssertionStrings then begin
  LookAssertionString:=Instance.LookAssertionStrings[WhichLookAssertionString];
  LookAssertionStringLength:=length(LookAssertionString);
  if LookBehind then begin
   if Position>=LookAssertionStringLength then begin
    result:=true;
    for Index:=0 to LookAssertionStringLength-1 do begin
     if Input[Position-Index-1]<>LookAssertionString[LookAssertionStringLength-Index] then begin   // -1 added KV
      result:=false;
      break;
     end;
    end;
   end else begin
    result:=false;
   end;
  end else begin
   if (Position+LookAssertionStringLength)<=InputLength then begin
    result:=true;
    BasePosition:=Position;
    if rfUTF8 in Instance.Flags then begin
     UTF8PtrSafeInc(Input,InputLength,BasePosition);
     dec(BasePosition);
    end;
    for Index:=1 to LookAssertionStringLength do begin
     if Input[BasePosition+Index-1]<>LookAssertionString[Index] then begin   // -1 added kv
      result:=false;
      break;
     end;
    end;
   end else begin
    result:=false;
   end;
  end;
 end else begin
  result:=false;
 end;
 result:=result xor Negative;
end;
pyscripter commented 6 years ago

Thanks!