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

OnePassNFA is used without first calling CompileOnePassNFA #43

Closed pyscripter closed 6 years ago

pyscripter commented 6 years ago

The following from issue #27 crashes FLRE.

f := TFLRE.Create('a(?!b)', []);
 writeln(f.Test('ab')); //=> EAccessViolation, State = nil in FLRE:7218 NextMatchCondition:=State^.

The problem is in FLRE.Create where the following code exists.


 if (fifHasLookAssertions in InternalFlags) or (fifHasBackReferences in InternalFlags) then begin
   Include(InternalFlags,fifOnePassNFAReady);
  end else begin
   CompileOnePassNFA;
  end;

Later in Test the OnePassNFA is used with having compiled it.

The fix is to remove the "end else begin". Here is the modified code:

if (fifHasLookAssertions in InternalFlags) or (fifHasBackReferences in InternalFlags) then begin
   Include(InternalFlags,fifOnePassNFAReady);
   CompileOnePassNFA;
  end;
pyscripter commented 6 years ago

You missed the Include(InternalFlags,fifOnePassNFAReady); Is this on purpose?

pyscripter commented 6 years ago

I think the fix is not correct you should still keep the second if

if (fifHasLookAssertions in InternalFlags) or (fifHasBackReferences in InternalFlags) then begin
   Include(InternalFlags,fifOnePassNFAReady);
   CompileOnePassNFA;
  end;

since if the regex has look assertions and/or backreferences the OnePassNFA can be tried, Also there is no need to CompileOnePassNFA if it is not going to be used.

BeRo1985 commented 6 years ago

The CompileOnePassNFA method procedure includes the Include(InternalFlags,fifOnePassNFAReady); as first statement

and the OnePass NFA should be only used, if >not< look assertions and back references are used, otherwise it would be pointless, when the OnePass NFA would be only used, if look assertions or back references are used. :-)