arged responses - #3418
Conversation
This add a args feature, for example if your arg is called `argreply`
You can do: `?reply Hello, read the following: {argreply}
fed5044
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Comments suppressed due to low confidence (5)
cogs/modmail.py:688
args_editstores the new value withoutcommands.clean_content, whileargs_addusesclean_content. This makes edits behave differently than adds and can reintroduce mentions/markdown thataddwould have sanitized.
@args.command(name="edit")
@checks.has_permissions(PermissionLevel.SUPPORTER)
async def args_edit(self, ctx, name: str.lower, *, value):
"""
Edit an arg.
cogs/modmail.py:1762
- Passing
**self.bot.argsalongside explicitchannel=...,recipient=...,author=...can raiseTypeError: got multiple values for keyword argumentif the config already contains any reserved keys (e.g. from manual edits or older data). Build a single kwargs dict and let the reserved keys override.
msg = self.bot.formatter.format(
msg,
**self.bot.args,
channel=ctx.channel,
recipient=ctx.thread.recipient,
cogs/modmail.py:1800
- Same reserved-key collision risk as
freply: expanding**self.bot.argstogether with explicitchannel/recipient/authorcan throwTypeErrorif those keys exist in config. Merge into a single dict so reserved values overwrite safely.
msg = self.bot.formatter.format(
msg,
**self.bot.args,
channel=ctx.channel,
recipient=ctx.thread.recipient,
cogs/modmail.py:1838
- Same reserved-key collision risk as
freply: expanding**self.bot.argstogether with explicitchannel/recipient/authorcan throwTypeErrorif those keys exist in config. Merge into a single dict so reserved values overwrite safely.
msg = self.bot.formatter.format(
msg,
**self.bot.args,
channel=ctx.channel,
recipient=ctx.thread.recipient,
cogs/modmail.py:1876
- Same reserved-key collision risk as
freply: expanding**self.bot.argstogether with explicitchannel/recipient/authorcan throwTypeErrorif those keys exist in config. Merge into a single dict so reserved values overwrite safely.
msg = self.bot.formatter.format(
msg,
**self.bot.args,
channel=ctx.channel,
recipient=ctx.thread.recipient,
sebkuip
left a comment
There was a problem hiding this comment.
Found a bug with dotted names within freply (and afreply likely as well)
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Suppressed comments (4)
cogs/modmail.py:30
RESERVED_ARG_NAMESonly blockschannel/recipient/author, but arg names that collide with theargssubcommands (add/remove/edit/rename/raw) or the specialcompactkeyword cannot be retrieved via?args <name>and will be interpreted as commands/modes instead. Treating these as reserved avoids confusing, unretrievable args.
# Arg names reserved by formatreply commands (channel, recipient, author).
RESERVED_ARG_NAMES = {"channel", "recipient", "author"}
cogs/modmail.py:595
- The embed page count calculation creates an extra empty page when
len(self.bot.args)is an exact multiple of 10 (e.g., 10 args -> 2 embeds, second has no fields).
embeds = [discord.Embed(color=self.bot.main_color) for _ in range((len(self.bot.args) // 10) + 1)]
cogs/modmail.py:698
args_addsanitizes the stored value viacommands.clean_content, butargs_editdoes not. This makes it possible to bypass mention/markup sanitization by editing an existing arg, and can lead to unexpected pings when args are expanded in replies.
@args.command(name="edit")
@checks.has_permissions(PermissionLevel.SUPPORTER)
async def args_edit(self, ctx, name: str.lower, *, value):
"""
Edit an arg.
"""
if name in self.bot.args:
self.bot.args[name] = value
await self.bot.config.update()
embed = discord.Embed(
title="Edited arg",
color=self.bot.main_color,
description=f'`{name}` will now be replaced with "{value}".',
)
core/models.py:366
- SafeFormatter.get_field now returns a kwarg value when the entire field_name matches a key (including dotted names like
recipient.name). This changes formatting precedence and allows values in kwargs (e.g., user-defined args) to shadow attribute/index resolution that previously would have been applied, which can break existing{recipient.name}/{channel.id}usage in formatreply when an arg uses the same dotted name.
class SafeFormatter(Formatter):
def get_field(self, field_name, args, kwargs):
if field_name in kwargs:
return kwargs[field_name], field_name
first, rest = _string.formatter_field_name_split(field_name)
sebkuip
left a comment
There was a problem hiding this comment.
Ignore previous review. Found a bug with copilots help
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Suppressed comments (7)
cogs/modmail.py:686
args_editdoes not sanitize the edited value (unlikeargs_add, which usescommands.clean_content). Since arg values are later injected into embeds, this allows introducing mention pings (e.g., @everyone) or other unsafe content via edits.
async def args_edit(self, ctx, name: str.lower, *, value):
cogs/modmail.py:595
- The paginator page count creates an extra empty embed when the number of args is an exact multiple of 10 (e.g., 10 args => 2 pages, second is blank).
embeds = [discord.Embed(color=self.bot.main_color) for _ in range((len(self.bot.args) // 10) + 1)]
cogs/modmail.py:1800
- Passing
**self.bot.argsalongside explicitchannel=.../recipient=.../author=...can raise aTypeErrorif the args dict contains any of those reserved keys (e.g., via manual config edits), breaking the command at runtime. Filter reserved keys before expanding the args dict.
msg = self.bot.formatter.format(
msg,
**self.bot.args,
channel=ctx.channel,
recipient=ctx.thread.recipient,
cogs/modmail.py:1838
- Passing
**self.bot.argsalongside explicitchannel=.../recipient=.../author=...can raise aTypeErrorif the args dict contains any of those reserved keys (e.g., via manual config edits), breaking the command at runtime. Filter reserved keys before expanding the args dict.
msg = self.bot.formatter.format(
msg,
**self.bot.args,
channel=ctx.channel,
recipient=ctx.thread.recipient,
cogs/modmail.py:1876
- Passing
**self.bot.argsalongside explicitchannel=.../recipient=.../author=...can raise aTypeErrorif the args dict contains any of those reserved keys (e.g., via manual config edits), breaking the command at runtime. Filter reserved keys before expanding the args dict.
msg = self.bot.formatter.format(
msg,
**self.bot.args,
channel=ctx.channel,
recipient=ctx.thread.recipient,
core/models.py:422
UnseenFormatter.get_fieldcurrently returns a literal for any non-decimal field not exactly present inkwargs, which prevents attribute/index resolution for known base variables. This breaks existing usages like{bot.user.display_name}incore/config_help.jsonwhen formatted viaUnseenFormatter()(seecogs/utility.py:1010).
if field_name in kwargs:
return kwargs[field_name], field_name
if field_name.isdecimal():
return super().get_field(field_name, args, kwargs)
return "{" + field_name + "}", field_name
cogs/modmail.py:1764
- Passing
**self.bot.argsalongside explicitchannel=.../recipient=.../author=...can raise aTypeErrorif the args dict contains any of those reserved keys (e.g., via manual config edits), breaking the command at runtime. Filter reserved keys before expanding the args dict.
This issue also appears in the following locations of the same file:
- line 1796
- line 1834
- line 1872
msg = self.bot.formatter.format(
msg,
**self.bot.args,
channel=ctx.channel,
recipient=ctx.thread.recipient,
sebkuip
left a comment
There was a problem hiding this comment.
Small things from copilot's suggestions that are confirmed bugs
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Suppressed comments (6)
core/models.py:422
- UnseenFormatter.get_field currently returns a literal placeholder for any field name that isn’t an exact key in kwargs, which prevents attribute/index access (e.g.
{bot.user.display_name}) from resolving. This breaks existing uses like formatting strings incore/config_help.jsonviaUnseenFormatter().format(..., bot=self.bot).
if field_name in kwargs:
return kwargs[field_name], field_name
if field_name.isdecimal():
return super().get_field(field_name, args, kwargs)
return "{" + field_name + "}", field_name
cogs/modmail.py:1836
- Expanding
**self.bot.argshere can raiseTypeError: got multiple values for keyword argumentif the args dict ever contains reserved keys likechannel/recipient/author(e.g. from manual config edits). Filter reserved names out before expanding.
**self.bot.args,
cogs/modmail.py:1760
- Expanding
**self.bot.argshere can raiseTypeError: got multiple values for keyword argumentif the args dict ever contains reserved keys likechannel/recipient/author(e.g. from manual config edits). Filter reserved names out before expanding.
**self.bot.args,
cogs/modmail.py:1798
- Expanding
**self.bot.argshere can raiseTypeError: got multiple values for keyword argumentif the args dict ever contains reserved keys likechannel/recipient/author(e.g. from manual config edits). Filter reserved names out before expanding.
**self.bot.args,
cogs/modmail.py:1874
- Expanding
**self.bot.argshere can raiseTypeError: got multiple values for keyword argumentif the args dict ever contains reserved keys likechannel/recipient/author(e.g. from manual config edits). Filter reserved names out before expanding.
**self.bot.args,
cogs/modmail.py:555
- This help string includes
{arg-name}. Help text is rendered withhelp_.format(prefix=...)(seecogs/utility.py:111-112), so unescaped braces here can raise a formatting error. Use doubled braces to display a literal{...}to users.
You can use your arg in a reply with `{arg-name}`.
sebkuip
left a comment
There was a problem hiding this comment.
Look all good now. Can't find further bugs myself
This add a args feature, for example if your arg is called
argreplyYou can do: `?reply Hello, read the following: {argreply}