2020-08-11 00:53:43 +02:00
|
|
|
// Copyright (c) Microsoft Corporation
|
|
|
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
|
|
|
|
|
|
using System;
|
2021-07-05 16:26:31 +02:00
|
|
|
using System.Linq;
|
2022-01-11 12:13:41 +00:00
|
|
|
using System.Text.RegularExpressions;
|
2020-08-11 00:53:43 +02:00
|
|
|
using Microsoft.Plugin.Uri.Interfaces;
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.Plugin.Uri.UriHelper
|
|
|
|
|
{
|
|
|
|
|
public class ExtendedUriParser : IUriParser
|
|
|
|
|
{
|
2022-01-25 20:31:57 +02:00
|
|
|
// When updating this method, also update the local method IsUri() in Community.PowerToys.Run.Plugin.WebSearch.Main.Query
|
2021-11-17 06:06:45 +08:00
|
|
|
public bool TryParse(string input, out System.Uri result, out bool isWebUri)
|
2020-08-11 00:53:43 +02:00
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(input))
|
|
|
|
|
{
|
|
|
|
|
result = default;
|
2021-11-17 06:06:45 +08:00
|
|
|
isWebUri = false;
|
2020-08-11 00:53:43 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-17 06:06:45 +08:00
|
|
|
// Handling URL with only scheme, typically mailto or application uri.
|
|
|
|
|
// Do nothing, return the result without urlBuilder
|
2022-01-11 12:13:41 +00:00
|
|
|
// And check if scheme match REC3986 (issue #15035)
|
|
|
|
|
const string schemeRegex = @"^([a-z][a-z0-9+\-.]*):";
|
2021-11-17 06:06:45 +08:00
|
|
|
if (input.EndsWith(":", StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
&& !input.StartsWith("http", StringComparison.OrdinalIgnoreCase)
|
2022-03-10 11:35:13 +01:00
|
|
|
&& !input.Contains('/', StringComparison.OrdinalIgnoreCase)
|
2022-01-11 12:13:41 +00:00
|
|
|
&& !input.All(char.IsDigit)
|
|
|
|
|
&& Regex.IsMatch(input, schemeRegex))
|
2021-11-17 06:06:45 +08:00
|
|
|
{
|
|
|
|
|
result = new System.Uri(input);
|
|
|
|
|
isWebUri = false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-11 00:53:43 +02:00
|
|
|
// Handle common cases UriBuilder does not handle
|
2020-10-30 16:43:09 -07:00
|
|
|
// Using CurrentCulture since this is a user typed string
|
|
|
|
|
if (input.EndsWith(":", StringComparison.CurrentCulture)
|
|
|
|
|
|| input.EndsWith(".", StringComparison.CurrentCulture)
|
2021-07-05 16:26:31 +02:00
|
|
|
|| input.EndsWith(":/", StringComparison.CurrentCulture)
|
2021-11-17 06:06:45 +08:00
|
|
|
|| input.EndsWith("://", StringComparison.CurrentCulture)
|
2021-07-05 16:26:31 +02:00
|
|
|
|| input.All(char.IsDigit))
|
2020-08-11 00:53:43 +02:00
|
|
|
{
|
|
|
|
|
result = default;
|
2021-11-17 06:06:45 +08:00
|
|
|
isWebUri = false;
|
2020-08-11 00:53:43 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var urlBuilder = new UriBuilder(input);
|
2021-07-16 06:38:26 -05:00
|
|
|
var hadDefaultPort = urlBuilder.Uri.IsDefaultPort;
|
|
|
|
|
urlBuilder.Port = hadDefaultPort ? -1 : urlBuilder.Port;
|
|
|
|
|
|
2021-11-17 06:06:45 +08:00
|
|
|
if (input.StartsWith("HTTP://", StringComparison.OrdinalIgnoreCase))
|
2021-10-05 01:56:27 +08:00
|
|
|
{
|
|
|
|
|
urlBuilder.Scheme = System.Uri.UriSchemeHttp;
|
2021-11-17 06:06:45 +08:00
|
|
|
isWebUri = true;
|
2021-10-05 01:56:27 +08:00
|
|
|
}
|
2022-03-10 11:35:13 +01:00
|
|
|
else if (input.Contains(':', StringComparison.OrdinalIgnoreCase) &&
|
2021-11-17 06:06:45 +08:00
|
|
|
!input.StartsWith("http", StringComparison.OrdinalIgnoreCase) &&
|
2022-03-10 11:35:13 +01:00
|
|
|
!input.Contains('[', StringComparison.OrdinalIgnoreCase))
|
2021-10-05 01:56:27 +08:00
|
|
|
{
|
|
|
|
|
// Do nothing, leave unchanged
|
2021-11-17 06:06:45 +08:00
|
|
|
isWebUri = false;
|
2021-10-05 01:56:27 +08:00
|
|
|
}
|
|
|
|
|
else
|
2021-07-16 06:38:26 -05:00
|
|
|
{
|
|
|
|
|
urlBuilder.Scheme = System.Uri.UriSchemeHttps;
|
2021-11-17 06:06:45 +08:00
|
|
|
isWebUri = true;
|
2021-07-16 06:38:26 -05:00
|
|
|
}
|
2020-08-11 00:53:43 +02:00
|
|
|
|
|
|
|
|
result = urlBuilder.Uri;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2021-11-17 06:06:45 +08:00
|
|
|
catch (UriFormatException)
|
2020-08-11 00:53:43 +02:00
|
|
|
{
|
|
|
|
|
result = default;
|
2021-11-17 06:06:45 +08:00
|
|
|
isWebUri = false;
|
2020-08-11 00:53:43 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|