diff --git a/v2rayN/ServiceLib/Models/ProfileItem.cs b/v2rayN/ServiceLib/Models/ProfileItem.cs index da34600b..8f883535 100644 --- a/v2rayN/ServiceLib/Models/ProfileItem.cs +++ b/v2rayN/ServiceLib/Models/ProfileItem.cs @@ -109,6 +109,42 @@ public class ProfileItem : ReactiveObject return true; } + public async Task HasCycle(HashSet visited, HashSet stack) + { + if (ConfigType < EConfigType.Group) + return false; + + if (stack.Contains(IndexId)) + return true; + + if (visited.Contains(IndexId)) + return false; + + visited.Add(IndexId); + stack.Add(IndexId); + + if (ProfileGroupItemManager.Instance.TryGet(IndexId, out var group) + && !group.ChildItems.IsNullOrEmpty()) + { + var childProfiles = (await Task.WhenAll( + Utils.String2List(group.ChildItems) + .Where(p => !p.IsNullOrEmpty()) + .Select(AppManager.Instance.GetProfileItem) + )) + .Where(p => p != null) + .ToList(); + + foreach (var child in childProfiles) + { + if (await child.HasCycle(visited, stack)) + return true; + } + } + + stack.Remove(IndexId); + return false; + } + #endregion function [PrimaryKey] diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs index bd03b4c8..8bc93e71 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs @@ -217,9 +217,15 @@ public partial class CoreConfigSingboxService { return -1; } + + var hasCycle = await node.HasCycle(new HashSet(), new HashSet()); + if (hasCycle) + { + return -1; + } + // remove custom nodes // remove group nodes for proxy chain - // avoid self-reference var childProfiles = (await Task.WhenAll( Utils.String2List(profileGroupItem.ChildItems) .Where(p => !p.IsNullOrEmpty()) @@ -230,7 +236,6 @@ public partial class CoreConfigSingboxService && p.IsValid() && p.ConfigType != EConfigType.Custom && (node.ConfigType == EConfigType.PolicyGroup || p.ConfigType < EConfigType.Group) - && p.IndexId != node.IndexId ) .ToList(); diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs index b250e01d..3d6597ae 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs @@ -493,6 +493,13 @@ public partial class CoreConfigV2rayService { return -1; } + + var hasCycle = await node.HasCycle(new HashSet(), new HashSet()); + if (hasCycle) + { + return -1; + } + // remove custom nodes // remove group nodes for proxy chain var childProfiles = (await Task.WhenAll(