From a99baf29695128d72874d8c4ccad3e90c90e53be Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Sat, 13 Jan 2024 12:04:14 +0100 Subject: [PATCH] Replaced RegEx with IndexOf/Substring to avoid RegexMatchTimeoutException --- .../Validations/Rules/OpenApiPathsRules.cs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiPathsRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiPathsRules.cs index d94f7a31a..d248edb3c 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiPathsRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiPathsRules.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Text.RegularExpressions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Properties; @@ -36,7 +35,6 @@ public static class OpenApiPathsRules } }); - private static readonly Regex regexPath = new Regex("\\{([^/}]+)\\}", RegexOptions.Compiled, TimeSpan.FromMilliseconds(100)); /// /// A relative path to an individual endpoint. The field name MUST begin with a slash. /// @@ -50,7 +48,7 @@ public static class OpenApiPathsRules { context.Enter(path); - var pathSignature = regexPath.Replace(path, "{}"); + var pathSignature = GetPathSignature(path); if (!hashSet.Add(pathSignature)) context.CreateError(nameof(PathMustBeUnique), @@ -60,6 +58,28 @@ public static class OpenApiPathsRules } }); + /// + /// Replaces placeholders in the path with {}, e.g. /pets/{petId} becomes /pets/{} . + /// + /// The input path + /// The path signature + private static string GetPathSignature(string path) + { + for (int openBrace = path.IndexOf('{'); openBrace > -1; openBrace = path.IndexOf('{', openBrace + 2)) + { + int closeBrace = path.IndexOf('}', openBrace); + + if (closeBrace < 0) + { + return path; + } + + path = path.Substring(0, openBrace + 1) + path.Substring(closeBrace); + } + + return path; + } + // add more rules } }