Skip to content

Commit f6a3836

Browse files
fixes#319 - V2Deserializer should handle invalid host value gracefully
1 parent f1864c6 commit f6a3836

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Generic;
66
using System.Globalization;
77
using System.Linq;
8+
using Microsoft.OpenApi.Exceptions;
89
using Microsoft.OpenApi.Extensions;
910
using Microsoft.OpenApi.Interfaces;
1011
using Microsoft.OpenApi.Models;
@@ -122,18 +123,26 @@ internal static partial class OpenApiV2Deserializer
122123
{s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))}
123124
};
124125

125-
private static void MakeServers(IList<OpenApiServer> servers, ParsingContext context, Uri defaultUrl)
126+
private static void MakeServers(IList<OpenApiServer> servers, ParsingContext context, RootNode rootNode)
126127
{
127128
var host = context.GetFromTempStorage<string>("host");
128129
var basePath = context.GetFromTempStorage<string>("basePath");
129130
var schemes = context.GetFromTempStorage<List<string>>("schemes");
131+
Uri defaultUrl = rootNode.Context.BaseUrl;
130132

131133
// If nothing is provided, don't create a server
132134
if (host == null && basePath == null && schemes == null)
133135
{
134136
return;
135137
}
136138

139+
//Validate host
140+
if (host != null && !IsHostValid(host))
141+
{
142+
rootNode.Diagnostic.Errors.Add(new OpenApiError(new OpenApiException("Invalid host")));
143+
return;
144+
}
145+
137146
// Fill in missing information based on the defaultUrl
138147
if (defaultUrl != null)
139148
{
@@ -226,7 +235,7 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode)
226235
openApidoc.Servers = new List<OpenApiServer>();
227236
}
228237

229-
MakeServers(openApidoc.Servers, openApiNode.Context, rootNode.Context.BaseUrl);
238+
MakeServers(openApidoc.Servers, openApiNode.Context, rootNode);
230239

231240
FixRequestBodyReferences(openApidoc);
232241
return openApidoc;
@@ -243,6 +252,26 @@ private static void FixRequestBodyReferences(OpenApiDocument doc)
243252
walker.Walk(doc);
244253
}
245254
}
255+
256+
private static bool IsHostValid(string host)
257+
{
258+
try
259+
{
260+
//Check if the host contains ://
261+
if (host.Contains(Uri.SchemeDelimiter))
262+
{
263+
return false;
264+
}
265+
266+
//Check if the host (excluding port number) is a valid dns/ip address.
267+
var hostPart = host.Split(':').First();
268+
return Uri.CheckHostName(hostPart) != UriHostNameType.Unknown;
269+
}
270+
catch (Exception)
271+
{
272+
return false;
273+
}
274+
}
246275
}
247276

248277
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 InvalidHostShouldYieldDiagnostic()
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+
Assert.Equal(0, doc.Servers.Count);
282+
diagnostic.ShouldBeEquivalentTo(
283+
new OpenApiDiagnostic
284+
{
285+
Errors =
286+
{
287+
new OpenApiError(new OpenApiException("Invalid host"))
288+
},
289+
SpecificationVersion = OpenApiSpecVersion.OpenApi2_0
290+
});
291+
}
292+
260293
}
261294
}

0 commit comments

Comments
 (0)