From 0e9cd54c2ec4bd7451230657bbcafe57c9a519a9 Mon Sep 17 00:00:00 2001 From: James Doran Date: Mon, 17 Feb 2020 18:06:40 +1030 Subject: [PATCH] Fixed stackoverflow when finding ancestors (#247) --- .../Services/Extensions/WorkflowExtensions.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/core/Elsa.Abstractions/Services/Extensions/WorkflowExtensions.cs b/src/core/Elsa.Abstractions/Services/Extensions/WorkflowExtensions.cs index 1db659d43..0eb90043d 100644 --- a/src/core/Elsa.Abstractions/Services/Extensions/WorkflowExtensions.cs +++ b/src/core/Elsa.Abstractions/Services/Extensions/WorkflowExtensions.cs @@ -58,24 +58,31 @@ namespace Elsa.Services.Extensions /// public static IEnumerable GetInboundActivityPath(this Workflow workflow, string activityId) { - return workflow.GetInboundActivityPathInternal(activityId, activityId).Distinct().ToList(); + var inspectedActivityIDs = new HashSet(); + + return workflow.GetInboundActivityPathInternal(activityId, activityId, inspectedActivityIDs) + .Distinct().ToList(); } private static IEnumerable GetInboundActivityPathInternal(this Workflow workflowInstance, - string activityId, string startingPointActivityId) + string activityId, + string startingPointActivityId, + HashSet inspectedActivityIDs) { foreach (var connection in workflowInstance.GetInboundConnections(activityId)) { // Circuit breaker: Detect workflows that implement repeating flows to prevent an infinite loop here. - if (connection.Source.Activity.Id == startingPointActivityId) + if (inspectedActivityIDs.Contains(connection.Source.Activity.Id)) yield break; yield return connection.Source.Activity.Id; - foreach (var parentActivityId in workflowInstance - .GetInboundActivityPathInternal(connection.Source.Activity.Id, startingPointActivityId) - .Distinct()) + foreach (var parentActivityId in workflowInstance.GetInboundActivityPathInternal(connection.Source.Activity.Id, startingPointActivityId, inspectedActivityIDs) + .Distinct()) + { + inspectedActivityIDs.Add(parentActivityId); yield return parentActivityId; + } } } }