fix: Guarding against empty descriptions in SlashCommandBuilder/SlashCommandOptionBuilder (#2260)
* adding null/empty check for option-descriptions * moving check to Preconditions * docs
This commit is contained in:
@@ -198,21 +198,13 @@ namespace Discord
|
|||||||
string description, bool? isRequired = null, bool? isDefault = null, bool isAutocomplete = false, double? minValue = null, double? maxValue = null,
|
string description, bool? isRequired = null, bool? isDefault = null, bool isAutocomplete = false, double? minValue = null, double? maxValue = null,
|
||||||
List<SlashCommandOptionBuilder> options = null, List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
|
List<SlashCommandOptionBuilder> options = null, List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
|
||||||
{
|
{
|
||||||
// Make sure the name matches the requirements from discord
|
Preconditions.Options(name, description);
|
||||||
Preconditions.NotNullOrEmpty(name, nameof(name));
|
|
||||||
Preconditions.AtLeast(name.Length, 1, nameof(name));
|
|
||||||
Preconditions.AtMost(name.Length, MaxNameLength, nameof(name));
|
|
||||||
|
|
||||||
// Discord updated the docs, this regex prevents special characters like @!$%( and s p a c e s.. etc,
|
// Discord updated the docs, this regex prevents special characters like @!$%( and s p a c e s.. etc,
|
||||||
// https://discord.com/developers/docs/interactions/slash-commands#applicationcommand
|
// https://discord.com/developers/docs/interactions/slash-commands#applicationcommand
|
||||||
if (!Regex.IsMatch(name, @"^[\w-]{1,32}$"))
|
if (!Regex.IsMatch(name, @"^[\w-]{1,32}$"))
|
||||||
throw new ArgumentException("Command name cannot contain any special characters or whitespaces!", nameof(name));
|
throw new ArgumentException("Command name cannot contain any special characters or whitespaces!", nameof(name));
|
||||||
|
|
||||||
// same with description
|
|
||||||
Preconditions.NotNullOrEmpty(description, nameof(description));
|
|
||||||
Preconditions.AtLeast(description.Length, 1, nameof(description));
|
|
||||||
Preconditions.AtMost(description.Length, MaxDescriptionLength, nameof(description));
|
|
||||||
|
|
||||||
// make sure theres only one option with default set to true
|
// make sure theres only one option with default set to true
|
||||||
if (isDefault == true && Options?.Any(x => x.IsDefault == true) == true)
|
if (isDefault == true && Options?.Any(x => x.IsDefault == true) == true)
|
||||||
throw new ArgumentException("There can only be one command option with default set to true!", nameof(isDefault));
|
throw new ArgumentException("There can only be one command option with default set to true!", nameof(isDefault));
|
||||||
@@ -248,6 +240,7 @@ namespace Discord
|
|||||||
throw new InvalidOperationException($"Cannot have more than {MaxOptionsCount} options!");
|
throw new InvalidOperationException($"Cannot have more than {MaxOptionsCount} options!");
|
||||||
|
|
||||||
Preconditions.NotNull(option, nameof(option));
|
Preconditions.NotNull(option, nameof(option));
|
||||||
|
Preconditions.Options(option.Name, option.Description); // this is a double-check when this method is called via AddOption(string name... )
|
||||||
|
|
||||||
Options.Add(option);
|
Options.Add(option);
|
||||||
return this;
|
return this;
|
||||||
@@ -270,6 +263,9 @@ namespace Discord
|
|||||||
if (Options.Count + options.Length > MaxOptionsCount)
|
if (Options.Count + options.Length > MaxOptionsCount)
|
||||||
throw new ArgumentOutOfRangeException(nameof(options), $"Cannot have more than {MaxOptionsCount} options!");
|
throw new ArgumentOutOfRangeException(nameof(options), $"Cannot have more than {MaxOptionsCount} options!");
|
||||||
|
|
||||||
|
foreach (var option in options)
|
||||||
|
Preconditions.Options(option.Name, option.Description);
|
||||||
|
|
||||||
Options.AddRange(options);
|
Options.AddRange(options);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -434,21 +430,13 @@ namespace Discord
|
|||||||
string description, bool? isRequired = null, bool isDefault = false, bool isAutocomplete = false, double? minValue = null, double? maxValue = null,
|
string description, bool? isRequired = null, bool isDefault = false, bool isAutocomplete = false, double? minValue = null, double? maxValue = null,
|
||||||
List<SlashCommandOptionBuilder> options = null, List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
|
List<SlashCommandOptionBuilder> options = null, List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
|
||||||
{
|
{
|
||||||
// Make sure the name matches the requirements from discord
|
Preconditions.Options(name, description);
|
||||||
Preconditions.NotNullOrEmpty(name, nameof(name));
|
|
||||||
Preconditions.AtLeast(name.Length, 1, nameof(name));
|
|
||||||
Preconditions.AtMost(name.Length, SlashCommandBuilder.MaxNameLength, nameof(name));
|
|
||||||
|
|
||||||
// Discord updated the docs, this regex prevents special characters like @!$%( and s p a c e s.. etc,
|
// Discord updated the docs, this regex prevents special characters like @!$%( and s p a c e s.. etc,
|
||||||
// https://discord.com/developers/docs/interactions/slash-commands#applicationcommand
|
// https://discord.com/developers/docs/interactions/slash-commands#applicationcommand
|
||||||
if (!Regex.IsMatch(name, @"^[\w-]{1,32}$"))
|
if (!Regex.IsMatch(name, @"^[\w-]{1,32}$"))
|
||||||
throw new ArgumentException("Command name cannot contain any special characters or whitespaces!", nameof(name));
|
throw new ArgumentException("Command name cannot contain any special characters or whitespaces!", nameof(name));
|
||||||
|
|
||||||
// same with description
|
|
||||||
Preconditions.NotNullOrEmpty(description, nameof(description));
|
|
||||||
Preconditions.AtLeast(description.Length, 1, nameof(description));
|
|
||||||
Preconditions.AtMost(description.Length, SlashCommandBuilder.MaxDescriptionLength, nameof(description));
|
|
||||||
|
|
||||||
// make sure theres only one option with default set to true
|
// make sure theres only one option with default set to true
|
||||||
if (isDefault && Options?.Any(x => x.IsDefault == true) == true)
|
if (isDefault && Options?.Any(x => x.IsDefault == true) == true)
|
||||||
throw new ArgumentException("There can only be one command option with default set to true!", nameof(isDefault));
|
throw new ArgumentException("There can only be one command option with default set to true!", nameof(isDefault));
|
||||||
@@ -483,6 +471,7 @@ namespace Discord
|
|||||||
throw new InvalidOperationException($"There can only be {SlashCommandBuilder.MaxOptionsCount} options per sub command group!");
|
throw new InvalidOperationException($"There can only be {SlashCommandBuilder.MaxOptionsCount} options per sub command group!");
|
||||||
|
|
||||||
Preconditions.NotNull(option, nameof(option));
|
Preconditions.NotNull(option, nameof(option));
|
||||||
|
Preconditions.Options(option.Name, option.Description); // double check again
|
||||||
|
|
||||||
Options.Add(option);
|
Options.Add(option);
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -297,5 +297,22 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region SlashCommandOptions
|
||||||
|
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="description"/> or <paramref name="name"/> is null.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="description"/> or <paramref name="name"/> are either empty or their length exceed limits.</exception>
|
||||||
|
public static void Options(string name, string description)
|
||||||
|
{
|
||||||
|
// Make sure the name matches the requirements from discord
|
||||||
|
NotNullOrEmpty(name, nameof(name));
|
||||||
|
NotNullOrEmpty(description, nameof(description));
|
||||||
|
AtLeast(name.Length, 1, nameof(name));
|
||||||
|
AtMost(name.Length, SlashCommandBuilder.MaxNameLength, nameof(name));
|
||||||
|
AtLeast(description.Length, 1, nameof(description));
|
||||||
|
AtMost(description.Length, SlashCommandBuilder.MaxDescriptionLength, nameof(description));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user