Skip to content

Commit bb960b3

Browse files
authored
Merge pull request #340 from senthilkumarmohan/bugfix#319-V2Deserializer-should-handle-invalid-host-value-gracefully
fixes#319 - V2Deserializer should handle invalid host value gracefully
2 parents 2ac0b8c + addd6e1 commit bb960b3

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,18 +122,26 @@ internal static partial class OpenApiV2Deserializer
122122
{s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))}
123123
};
124124

125-
private static void MakeServers(IList<OpenApiServer> servers, ParsingContext context, Uri defaultUrl)
125+
private static void MakeServers(IList<OpenApiServer> servers, ParsingContext context, RootNode rootNode)
126126
{
127127
var host = context.GetFromTempStorage<string>("host");
128128
var basePath = context.GetFromTempStorage<string>("basePath");
129129
var schemes = context.GetFromTempStorage<List<string>>("schemes");
130+
Uri defaultUrl = rootNode.Context.BaseUrl;
130131

131132
// If nothing is provided, don't create a server
132133
if (host == null && basePath == null && schemes == null)
133134
{
134135
return;
135136
}
136137

138+
//Validate host
139+
if (host != null && !IsHostValid(host))
140+
{
141+
rootNode.Diagnostic.Errors.Add(new OpenApiError(rootNode.Context.GetLocation(), "Invalid host"));
142+
return;
143+
}
144+
137145
// Fill in missing information based on the defaultUrl
138146
if (defaultUrl != null)
139147
{
@@ -226,7 +234,7 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode)
226234
openApidoc.Servers = new List<OpenApiServer>();
227235
}
228236

229-
MakeServers(openApidoc.Servers, openApiNode.Context, rootNode.Context.BaseUrl);
237+
MakeServers(openApidoc.Servers, openApiNode.Context, rootNode);
230238

231239
FixRequestBodyReferences(openApidoc);
232240
return openApidoc;
@@ -243,6 +251,19 @@ private static void FixRequestBodyReferences(OpenApiDocument doc)
243251
walker.Walk(doc);
244252
}
245253
}
254+
255+
private static bool IsHostValid(string host)
256+
{
257+
//Check if the host contains ://
258+
if (host.Contains(Uri.SchemeDelimiter))
259+
{
260+
return false;
261+
}
262+
263+
//Check if the host (excluding port number) is a valid dns/ip address.
264+
var hostPart = host.Split(':').First();
265+
return Uri.CheckHostName(hostPart) != UriHostNameType.Unknown;
266+
}
246267
}
247268

248269
internal class RequestBodyReferenceFixer : OpenApiVisitorBase

test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System;
1+
using FluentAssertions;
2+
using Microsoft.OpenApi.Exceptions;
3+
using Microsoft.OpenApi.Models;
4+
using System;
25
using System.Collections.Generic;
36
using System.Linq;
47
using System.Text;
@@ -257,5 +260,35 @@ public void LocalHostWithCustomHost()
257260
Assert.Equal(1, doc.Servers.Count);
258261
Assert.Equal("https://localhost:23232", server.Url);
259262
}
263+
264+
[Fact]
265+
public void InvalidHostShouldYieldError()
266+
{
267+
var input = @"
268+
swagger: 2.0
269+
info:
270+
title: test
271+
version: 1.0.0
272+
host: http://test.microsoft.com
273+
paths: {}
274+
";
275+
var reader = new OpenApiStringReader(new OpenApiReaderSettings()
276+
{
277+
BaseUrl = new Uri("https://bing.com")
278+
});
279+
280+
var doc = reader.Read(input, out var diagnostic);
281+
doc.Servers.Count.Should().Be(0);
282+
diagnostic.ShouldBeEquivalentTo(
283+
new OpenApiDiagnostic
284+
{
285+
Errors =
286+
{
287+
new OpenApiError("#/", "Invalid host")
288+
},
289+
SpecificationVersion = OpenApiSpecVersion.OpenApi2_0
290+
});
291+
}
292+
260293
}
261294
}

0 commit comments

Comments
 (0)