From 1cc7886edfc960fcdd9203de9f58a13e0fe06ac3 Mon Sep 17 00:00:00 2001 From: wp Date: Tue, 12 Mar 2019 08:58:56 +0000 Subject: [PATCH] TAChart: Fix broadcasting of notifications when an exception occurs. Issue #35210, patch by Marcin Wiazowski. git-svn-id: trunk@60657 - --- components/tachart/tachartutils.pas | 36 ++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/components/tachart/tachartutils.pas b/components/tachart/tachartutils.pas index 9b3e669ed8..d6afa1a2c6 100644 --- a/components/tachart/tachartutils.pas +++ b/components/tachart/tachartutils.pas @@ -43,6 +43,7 @@ const type EChartError = class(Exception); EChartIntervalError = class(EChartError); + EBroadcasterError = class(EChartError); EListenerError = class(EChartError); EDrawDataError = class(EChartError); @@ -847,11 +848,40 @@ end; procedure TBroadcaster.Broadcast(ASender: TObject); var - p: Pointer; + ListCopy: array of Pointer; + Exceptions: TStringList; + i: Integer; begin if Locked then exit; - for p in Self do - TListener(p).Notify(ASender); + if Count = 0 then exit; + + // Listeners can remove themselves when being notified, which + // changes the list - so we must use a copy of the list when + // notifying, to avoid omissions in notifying + SetLength(ListCopy, Count); + for i := 0 to High(ListCopy) do + ListCopy[i] := List^[i]; + + Exceptions := nil; + try + for i := 0 to High(ListCopy) do + try + TListener(ListCopy[i]).Notify(ASender); + except + on E: Exception do begin + if not Assigned(Exceptions) then begin + Exceptions := TStringList.Create; + Exceptions.Duplicates := dupIgnore; + Exceptions.Sorted := true; // required by dupIgnore + end; + Exceptions.Add(E.Message); + end; + end; + if Assigned(Exceptions) then + raise EBroadcasterError.Create(Trim(Exceptions.Text)); + finally + Exceptions.Free; + end; end; destructor TBroadcaster.Destroy;