diff --git a/PluralKit.API/Utils/JsonModelExt.cs b/PluralKit.API/Utils/JsonModelExt.cs index d6d6ddf9..af4d62f6 100644 --- a/PluralKit.API/Utils/JsonModelExt.cs +++ b/PluralKit.API/Utils/JsonModelExt.cs @@ -31,7 +31,7 @@ namespace PluralKit.API if (o.ContainsKey("name")) system.Name = o.Value("name").NullIfEmpty().BoundsCheckField(Limits.MaxSystemNameLength, "System name"); if (o.ContainsKey("description")) system.Description = o.Value("description").NullIfEmpty().BoundsCheckField(Limits.MaxDescriptionLength, "System description"); if (o.ContainsKey("tag")) system.Tag = o.Value("tag").NullIfEmpty().BoundsCheckField(Limits.MaxSystemTagLength, "System tag"); - if (o.ContainsKey("avatar_url")) system.AvatarUrl = o.Value("avatar_url").NullIfEmpty(); + if (o.ContainsKey("avatar_url")) system.AvatarUrl = o.Value("avatar_url").NullIfEmpty().BoundsCheckField(Limits.MaxUriLength, "System avatar URL"); if (o.ContainsKey("tz")) system.UiTz = o.Value("tz") ?? "UTC"; if (o.ContainsKey("description_privacy")) system.DescriptionPrivacy = o.Value("description_privacy").ParsePrivacy("description"); diff --git a/PluralKit.Bot/Commands/MemberAvatar.cs b/PluralKit.Bot/Commands/MemberAvatar.cs index 9fee58c3..86e9f4d9 100644 --- a/PluralKit.Bot/Commands/MemberAvatar.cs +++ b/PluralKit.Bot/Commands/MemberAvatar.cs @@ -72,6 +72,7 @@ namespace PluralKit.Bot } else if (ctx.RemainderOrNull() is string url) { + if (url.Length > Limits.MaxUriLength) throw Errors.InvalidUrl(url); await AvatarUtils.VerifyAvatarOrThrow(url); target.AvatarUrl = url; await _data.SaveMember(target); @@ -141,6 +142,7 @@ namespace PluralKit.Bot } else if (ctx.RemainderOrNull() is string url) { + if (url.Length > Limits.MaxUriLength) throw Errors.InvalidUrl(url); await AvatarUtils.VerifyAvatarOrThrow(url); guildData.AvatarUrl = url; await _data.SetMemberGuildSettings(target, ctx.Guild.Id, guildData); diff --git a/PluralKit.Bot/Commands/SystemEdit.cs b/PluralKit.Bot/Commands/SystemEdit.cs index a4bd18b0..6da3b48e 100644 --- a/PluralKit.Bot/Commands/SystemEdit.cs +++ b/PluralKit.Bot/Commands/SystemEdit.cs @@ -156,6 +156,7 @@ namespace PluralKit.Bot { // They can't both be null - otherwise we would've hit the conditional at the very top string url = ctx.RemainderOrNull() ?? ctx.Message.Attachments.FirstOrDefault()?.ProxyUrl; + if (url?.Length > Limits.MaxUriLength) throw Errors.InvalidUrl(url); await ctx.BusyIndicator(() => AvatarUtils.VerifyAvatarOrThrow(url)); ctx.System.AvatarUrl = url; diff --git a/PluralKit.Bot/Errors.cs b/PluralKit.Bot/Errors.cs index bedd16b6..5156db2e 100644 --- a/PluralKit.Bot/Errors.cs +++ b/PluralKit.Bot/Errors.cs @@ -59,6 +59,7 @@ namespace PluralKit.Bot { public static PKError AvatarInvalid => new PKError($"Could not read image file - perhaps it's corrupted or the wrong format. Try a different image."); public static PKError UserHasNoAvatar => new PKError("The given user has no avatar set."); public static PKError InvalidUrl(string url) => new PKError($"The given URL is invalid."); + public static PKError UrlTooLong(string url) => new PKError($"The given URL is too long ({url.Length}/{Limits.MaxUriLength} characters)."); public static PKError AccountAlreadyLinked => new PKError("That account is already linked to your system."); public static PKError AccountNotLinked => new PKError("That account isn't linked to your system."); diff --git a/PluralKit.Core/Utils/Limits.cs b/PluralKit.Core/Utils/Limits.cs index 36fdbde0..8c863adb 100644 --- a/PluralKit.Core/Utils/Limits.cs +++ b/PluralKit.Core/Utils/Limits.cs @@ -10,7 +10,7 @@ namespace PluralKit.Core { public static readonly int MaxDescriptionLength = 1000; public static readonly int MaxMemberNameLength = 100; // Fair bit larger than MaxProxyNameLength for bookkeeping public static readonly int MaxPronounsLength = 100; - + public static readonly int MaxUriLength = 256; // May need to be set higher, I know there are URLs longer than this in prod (they can rehost, I guess...) public static readonly long AvatarFileSizeLimit = 1024 * 1024; public static readonly int AvatarDimensionLimit = 1000; }