sempare / sempare-delphi-template-engine

Sempare Template Engine for Delphi allows for flexible dynamic text generation. It can be used for generating email, html, reports, source code, xml, configuration, etc.
GNU General Public License v3.0
134 stars 18 forks source link

Concurrency issue #205

Closed craigmox closed 3 hours ago

craigmox commented 4 hours ago

I've found that usage of a class instance of TRegEx in Sempare.Template.Lexer.pas is not thread-safe and is causing memory corruption issues in my testing:

https://github.com/sempare/sempare-delphi-template-engine/blob/2bbdf4c158d5cfe6b2d03cc50991cff703368918/src/Sempare.Template.Lexer.pas#L272

  function IsValidId(const AId: string): Boolean;
  begin
    exit(FIDRegex.IsMatch(AId));
  end;

This is due to the implementation of IsMatch unfortunately using a field to store the input text:

function TRegEx.IsMatch(const Input: string): Boolean;
begin
  FRegEx.Subject := Input;
  Result := FRegEx.Match;
end;

I've found that System.SysUtils.IsValidIdent is a suitable replacement and has been working in my testing, just as one suggestion.

Thanks!

darnocian commented 3 hours ago

Ah. Good spot and great suggestion.

darnocian commented 3 hours ago

fix is on dev branch and will be pushed next week

darnocian commented 3 hours ago

Just wanted to check - where you testing with Template.Eval() methods, or via the template registry methods?

I'll add some more multithreaded tests.

craigmox commented 1 hour ago

I've been load testing one of our web services that funnels through the class function Template.Parse(const AContext: ITemplateContext; const AStream: TStream; const AManagedStream: boolean = true): ITemplate overload.