@@ -408,22 +408,22 @@ namespace Discord | |||||
if (Length > MaxEmbedLength) | if (Length > MaxEmbedLength) | ||||
throw new InvalidOperationException($"Total embed length must be less than or equal to {MaxEmbedLength}."); | throw new InvalidOperationException($"Total embed length must be less than or equal to {MaxEmbedLength}."); | ||||
if (!string.IsNullOrEmpty(Url)) | if (!string.IsNullOrEmpty(Url)) | ||||
UrlValidation.Validate(Url); | |||||
UrlValidation.Validate(Url, true); | |||||
if (!string.IsNullOrEmpty(ThumbnailUrl)) | if (!string.IsNullOrEmpty(ThumbnailUrl)) | ||||
UrlValidation.Validate(ThumbnailUrl); | |||||
if (!string.IsNullOrEmpty(ImageUrl) && !ImageUrl.StartsWith("attachment://", StringComparison.Ordinal)) | |||||
UrlValidation.Validate(ImageUrl); | |||||
UrlValidation.Validate(ThumbnailUrl, true); | |||||
if (!string.IsNullOrEmpty(ImageUrl)) | |||||
UrlValidation.Validate(ImageUrl, true); | |||||
if (Author != null) | if (Author != null) | ||||
{ | { | ||||
if (!string.IsNullOrEmpty(Author.Url)) | if (!string.IsNullOrEmpty(Author.Url)) | ||||
UrlValidation.Validate(Author.Url); | |||||
UrlValidation.Validate(Author.Url, true); | |||||
if (!string.IsNullOrEmpty(Author.IconUrl)) | if (!string.IsNullOrEmpty(Author.IconUrl)) | ||||
UrlValidation.Validate(Author.IconUrl); | |||||
UrlValidation.Validate(Author.IconUrl, true); | |||||
} | } | ||||
if(Footer != null) | if(Footer != null) | ||||
{ | { | ||||
if (!string.IsNullOrEmpty(Footer.IconUrl)) | if (!string.IsNullOrEmpty(Footer.IconUrl)) | ||||
UrlValidation.Validate(Footer.IconUrl); | |||||
UrlValidation.Validate(Footer.IconUrl, true); | |||||
} | } | ||||
var fields = ImmutableArray.CreateBuilder<EmbedField>(Fields.Count); | var fields = ImmutableArray.CreateBuilder<EmbedField>(Fields.Count); | ||||
for (int i = 0; i < Fields.Count; i++) | for (int i = 0; i < Fields.Count; i++) | ||||
@@ -9,14 +9,15 @@ namespace Discord.Utils | |||||
/// <see cref="ValidateButton(string)"/> should be used for url buttons. | /// <see cref="ValidateButton(string)"/> should be used for url buttons. | ||||
/// </summary> | /// </summary> | ||||
/// <param name="url">The URL to validate before sending to Discord.</param> | /// <param name="url">The URL to validate before sending to Discord.</param> | ||||
/// <param name="allowAttachments"><see langword="true"/> to allow the <b>attachment://</b> protocol; otherwise <see langword="false"/>.</param> | |||||
/// <exception cref="InvalidOperationException">A URL must include a protocol (http or https).</exception> | /// <exception cref="InvalidOperationException">A URL must include a protocol (http or https).</exception> | ||||
/// <returns>true if URL is valid by our standard, false if null, throws an error upon invalid.</returns> | /// <returns>true if URL is valid by our standard, false if null, throws an error upon invalid.</returns> | ||||
public static bool Validate(string url) | |||||
public static bool Validate(string url, bool allowAttachments = false) | |||||
{ | { | ||||
if (string.IsNullOrEmpty(url)) | if (string.IsNullOrEmpty(url)) | ||||
return false; | return false; | ||||
if (!(url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))) | |||||
throw new InvalidOperationException($"The url {url} must include a protocol (either HTTP or HTTPS)"); | |||||
if (!(url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || allowAttachments ? url.StartsWith("attachment://", StringComparison.Ordinal) : false)) | |||||
throw new InvalidOperationException($"The url {url} must include a protocol (either {(allowAttachments ? "HTTP, HTTPS, or ATTACHMENT" : "HTTP or HTTPS")})"); | |||||
return true; | return true; | ||||
} | } | ||||