Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/更新日志.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
V7.12.12
更新时间 2026-05-05

* OneBot 修复 get_forward_msg API 获取包含视频的聊天记录时报错
* OneBot 修复设置事件过滤器后导致反向 WS 频繁断线重连

=================
V7.12.11
更新时间 2026-05-03

Expand Down
2 changes: 0 additions & 2 deletions src/onebot11/connect/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ class OB11WebSocket {

const disposeHeartBeat = this.ctx.interval(() => {
const event = new OB11HeartbeatEvent(selfInfo.online!, true, this.config.heartInterval)
if (!matchEventFilter(this.config.filter, event)) return
this.reply(socket, event)
}, this.config.heartInterval)

Expand Down Expand Up @@ -337,7 +336,6 @@ class OB11WebSocketReverse {
const disposeHeartBeat = this.ctx.interval(() => {
if (this.wsClient) {
const event = new OB11HeartbeatEvent(selfInfo.online!, true, this.config.heartInterval)
if (!matchEventFilter(this.config.filter, event)) return
this.reply(this.wsClient, event)
}
}, this.config.heartInterval)
Expand Down
48 changes: 32 additions & 16 deletions src/onebot11/helper/decodeMultiMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,38 @@ export async function decodeMultiMessage(ctx: Context, items: InferProtoModel<ty
text: element.text.str!
}
}
} else if (element.commonElem && element.commonElem.serviceType === 48) {
const richMediaInfo = Media.MsgInfo.decode(element.commonElem.pbElem)
const infoBody = richMediaInfo.msgInfoBody[0]
const parsedUrl = new URL('https://' + infoBody.pic!.domain + infoBody.pic!.urlPath + infoBody.pic!.ext!.originalParam)
const imageAppid = parsedUrl.searchParams.get('appid')
const rkeyData = await ctx.ntFileApi.rkeyManager.getRkey()
const url = parsedUrl.href + (imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey)
const { info } = richMediaInfo.msgInfoBody[0].index!
const { pic } = richMediaInfo.extBizInfo!
segment = {
type: OB11MessageDataType.Image,
data: {
file: info!.fileName!,
subType: pic!.bizType!,
url,
file_size: info!.fileSize!.toString(),
} else if (element.commonElem) {
const { businessType, serviceType, pbElem } = element.commonElem
if (serviceType === 48 && (businessType === 10 || businessType === 20)) {
const richMediaInfo = Media.MsgInfo.decode(pbElem)
const infoBody = richMediaInfo.msgInfoBody[0]
const parsedUrl = new URL('https://' + infoBody.pic!.domain + infoBody.pic!.urlPath + infoBody.pic!.ext!.originalParam)
const imageAppid = parsedUrl.searchParams.get('appid')
const rkeyData = await ctx.ntFileApi.rkeyManager.getRkey()
const url = parsedUrl.href + (imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey)
const { info } = richMediaInfo.msgInfoBody[0].index!
const { pic } = richMediaInfo.extBizInfo!
segment = {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): 在解码视频消息时,需要防范 msgInfoBody[0].index 缺失或格式异常。

当前分支在没有任何检查的情况下直接解引用 msgInfoBody[0].index(包括其中的 fileUuidinfo 字段)。如果 msgInfoBody 为空,或者 index/info 缺失(例如上游 proto/服务端的问题),这里会抛异常并导致解码流水线崩溃。请添加一个最小化的防护(例如,当 msgInfoBody[0]?.index?.infofileUuid 缺失时直接提前返回),这样可以让格式异常的包以优雅失败的方式处理,而不是引发运行时错误。

Original comment in English

issue (bug_risk): Guard against missing or malformed msgInfoBody[0].index when decoding video messages.

This branch dereferences msgInfoBody[0].index (including fileUuid and info fields) without checks. If msgInfoBody is empty or index/info is absent (e.g., upstream proto/server issues), this will throw and can crash the decode pipeline. Please add a minimal guard (e.g., early-return when msgInfoBody[0]?.index?.info or fileUuid is missing) so malformed packets fail gracefully instead of causing runtime errors.

type: OB11MessageDataType.Image,
data: {
file: info!.fileName!,
subType: pic!.bizType!,
url,
file_size: info!.fileSize!.toString(),
}
}
} else if (serviceType === 48 && (businessType === 11 || businessType === 21)) {
const { msgInfoBody } = Media.MsgInfo.decode(pbElem)
const { index } = msgInfoBody[0]
const url = await ctx.ntFileApi.getVideoUrlByPacket(index.fileUuid, businessType === 21)
segment = {
type: OB11MessageDataType.Video,
data: {
file: index.info.fileName,
url,
path: '',
file_size: index.info.fileSize.toString(),
}
}
}
}
Expand Down
Loading