fix: reject a non-str stored token as stale before rebuilding the webhook (dpywebhooks-3)
Webhook.partial does no token validation of its own, so a store record with token=None (e.g. a mongo/file store deserializing a missing field as null) rebuilt and cached a token-less webhook with no error. Webhook.send then raised a raw ValueError, not HTTPException, so send()'s dead-webhook except never fired and the poisoned record was never cleared - the channel got permanently stuck. Validate the token type before partial() so a bad record takes the same clear-and-fall-through path as any other stale record. Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
@@ -351,11 +351,18 @@ class DPYWebhooks:
|
|||||||
|
|
||||||
async def _restore_from_store(self, channel: discord.TextChannel) -> "Optional[discord.Webhook]":
|
async def _restore_from_store(self, channel: discord.TextChannel) -> "Optional[discord.Webhook]":
|
||||||
"""rebuild a partial webhook from the stored record; on a rebuild fault, treat the
|
"""rebuild a partial webhook from the stored record; on a rebuild fault, treat the
|
||||||
record as stale (clear + return None so the caller can recreate)"""
|
record as stale (clear + return None so the caller can recreate)
|
||||||
|
|
||||||
|
Webhook.partial does no token validation of its own and will happily cache a
|
||||||
|
token-less webhook, which then raises a raw ValueError (not HTTPException) on
|
||||||
|
send - bypassing the self-heal path entirely and getting stuck forever. reject a
|
||||||
|
non-str token here, before partial(), so that record is treated as stale too"""
|
||||||
record = await self._store.get(channel.id)
|
record = await self._store.get(channel.id)
|
||||||
if not record:
|
if not record:
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
|
if not isinstance(record["token"], str):
|
||||||
|
raise TypeError(f"stored token must be str, got {type(record['token']).__name__}")
|
||||||
webhook = discord.Webhook.partial(
|
webhook = discord.Webhook.partial(
|
||||||
int(record["webhook_id"]),
|
int(record["webhook_id"]),
|
||||||
record["token"],
|
record["token"],
|
||||||
|
|||||||
Reference in New Issue
Block a user