diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiPathsRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiPathsRules.cs
index d94f7a31a..422accabc 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,38 @@ 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)
+ {
+ int i = 0;
+
+ while (i < path.Length)
+ {
+ int openBrace = path.IndexOf('{', i);
+
+ if (openBrace < 0)
+ {
+ return path;
+ }
+
+ int closeBrace = path.IndexOf('}', openBrace);
+
+ if (closeBrace < 0)
+ {
+ return path;
+ }
+
+ path = path.Substring(0, openBrace + 1) + path.Substring(closeBrace, path.Length - closeBrace);
+ i = openBrace + 2;
+ }
+
+ return path;
+ }
+
// add more rules
}
}