Files
PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/ExtendedUriParser.cs
Jeremy Sinclair 37f2154c86 [Analyzers] Resolve StyleCop issues: SA1516 and SA1616 (#34853)
* [Analyzers][AdvancedPaste] Apply fix for SA1516

* [Analyzers][EnvironmentVariables] Apply fix for SA1516

* [Analyzers][RegistryPreview] Apply fix for SA1516

* [Analyzers][Peek] Apply fix for SA1516

* [Analyzers][PreviewPane] Apply fix for SA1516

* [Analyzers][FancyZones] Apply fix for SA1516

* [Analyzers][PT Run][Plugins] Apply fix for SA1516

* [Analyzers][PT Run] Apply fix for SA1516

* [Analyzers][PT Run][Wox] Apply fix for SA1516

* [Analyzers][Common] Apply fix for SA1516

* [Analyzers][ImageResizer] Apply fix for SA1516

* [Analyzers][ColorPicker] Apply fix for SA1516

* [Analyzers][MouseUtils] Apply fix for SA1516

* [Analyzers][DSC Schema Generator] Apply fix for SA1516

* [Analyzers][FileLocksmith] Apply fix for SA1516

* [Analyzers][Hosts] Apply fix for SA1516

* [Analyzers][MeasureTool] Apply fix for SA1516

* [Analyzers][MouseWithoutBorders] Apply fix for SA1516

* [Analyzers][TextExtractor] Apply fix for SA1516

* [Analyzers][Workspaces] Apply fix for SA1516

* [Analyzers][Awake] Apply fix for SA1516

* [Analyzers][PowerAccent] Apply fix for SA1516

* [Analyzers][RegistryPreview] Apply fix for SA1516

* [Analyzers][Settings] Apply fix for SA1516

* [Analyzers][MouseWithoutBorders] Apply fix for SA1616
2024-09-16 21:09:43 +01:00

113 lines
4.5 KiB
C#

// 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;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Plugin.Uri.Interfaces;
namespace Microsoft.Plugin.Uri.UriHelper
{
public class ExtendedUriParser : IUriParser
{
// When updating this method, also update the local method IsUri() in Community.PowerToys.Run.Plugin.WebSearch.Main.Query
public bool TryParse(string input, out System.Uri webUri, out System.Uri systemUri)
{
webUri = default;
systemUri = default;
if (string.IsNullOrEmpty(input))
{
return false;
}
// Handling URL with only scheme, typically mailto or application uri.
// Do nothing, return the result without urlBuilder
// And check if scheme match RFC3986 (issue #15035)
const string schemeRegex = @"^([a-z][a-z0-9+\-.]*):";
if (input.EndsWith(":", StringComparison.OrdinalIgnoreCase)
&& !input.StartsWith("http", StringComparison.OrdinalIgnoreCase)
&& !input.Contains('/', StringComparison.OrdinalIgnoreCase)
&& !input.All(char.IsDigit)
&& Regex.IsMatch(input, schemeRegex))
{
systemUri = new System.Uri(input);
return true;
}
// Handle common cases UriBuilder does not handle
// Using CurrentCulture since this is a user typed string
if (input.EndsWith(":", StringComparison.CurrentCulture)
|| input.EndsWith(".", StringComparison.CurrentCulture)
|| input.EndsWith(":/", StringComparison.CurrentCulture)
|| input.EndsWith("://", StringComparison.CurrentCulture)
|| input.All(char.IsDigit))
{
return false;
}
try
{
string isDomainPortRegex = @"^[\w\.]+:\d+";
string isIPv6PortRegex = @"^\[([\w:]+:+)+[\w]+\]:\d+";
var urlBuilder = new UriBuilder(input);
urlBuilder.Port = urlBuilder.Uri.IsDefaultPort ? -1 : urlBuilder.Port;
if (input.StartsWith("HTTP://", StringComparison.OrdinalIgnoreCase))
{
urlBuilder.Scheme = System.Uri.UriSchemeHttp;
}
else if (Regex.IsMatch(input, isDomainPortRegex) ||
Regex.IsMatch(input, isIPv6PortRegex))
{
var secondUrlBuilder = urlBuilder;
try
{
urlBuilder = new UriBuilder("https://" + input);
if (urlBuilder.Port == 80)
{
urlBuilder.Scheme = System.Uri.UriSchemeHttp;
}
}
catch (UriFormatException)
{
// This handles the situation in tel:xxxx and others
// When xxxx > 65535, it will throw UriFormatException
// The catch ensures it will at least still try to return a systemUri
}
string singleLabelRegex = @"[\.:]+|^http$|^https$|^localhost$";
systemUri = Regex.IsMatch(urlBuilder.Host, singleLabelRegex) ? null : secondUrlBuilder.Uri;
}
else if (input.Contains(':', StringComparison.OrdinalIgnoreCase) &&
!input.StartsWith("http", StringComparison.OrdinalIgnoreCase) &&
!input.Contains('[', StringComparison.OrdinalIgnoreCase))
{
// Do nothing, leave unchanged
systemUri = urlBuilder.Uri;
}
else
{
urlBuilder.Scheme = System.Uri.UriSchemeHttps;
}
if (urlBuilder.Scheme.Equals(System.Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) ||
urlBuilder.Scheme.Equals(System.Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
{
webUri = urlBuilder.Uri;
}
return true;
}
catch (UriFormatException)
{
return false;
}
}
}
}