Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: 发送中文消息中包含单数空格或特殊字符会导致错误 #1295

Closed
3 tasks done
oicv opened this issue Dec 25, 2021 · 23 comments
Closed
3 tasks done
Labels
bug? The issue author think this is a bug

Comments

@oicv
Copy link

oicv commented Dec 25, 2021

请确保您已阅读以上注意事项,并勾选下方的确认框。

  • 我已经仔细阅读上述教程和 "提问前需知"
  • 我已知晓并同意,如果我不遵循以下格式提交 Issue,或者我使用的并非最新版本,或者我没有提供足够的环境信息,我的 Issue 可能会被无条件自动关闭或/并锁定。
  • 我已知晓并同意,此处仅用于汇报程序中存在的问题。若这个 Issue 是关于其他非程序本身问题,则我的 Issue 可能会被无条件自动关闭或/并锁定。(这些问题应当在 Discussion 板块提出。)

go-cqhttp 版本

v1.0.0-beta8-fix2

运行环境

CentOS

运行架构

AMD64

连接方式

WebSocket (反向)

使用协议

0 | iPad

重现步骤

使用反向WS发送如下内容:(action为send_guild_channel_msg)
{"guild_id":69327461639******,"channel_id":1769***,"message":"你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别人的梦。 "}

或使用HTTP发送如下内容以POST提交到/send_guild_channel_msg:
$post_data=array(
"guild_id"=>69327461639******,
"channel_id"=>1769***,
"message"=>"你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别 人的梦。"
);

只测试以上两种形式发送均无法正常发送

期望的结果是什么?

正常发送消息

实际的结果是什么?

使用反向WS和HTTP均报错

简单的复现代码/链接(可选)

以http post向框架提交如下内容到终结点/send_guild_channel_msg:
$post_data=array(
    "guild_id"=>69327461639******,
    "channel_id"=>1769***,
    "message"=>"你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别 人的梦。"
);

日志记录(可选)

**反向WS错误代码**
[2021-12-25 15:45:35] [DEBUG]: 向反向WS Universal服务器推送Event: {"channel_id":"180****","guild_id":"69327461639******","message":"77","message_id":"***-11360*****","message_type":"guild","post_type":"message","self_id":342431****,"self_tiny_id":"144115218679******","sender":{"nickname":"‭","user_id":"144115218678******"},"sub_type":"channel","time":1640418335,"user_id":"144115218678******"}
 
[2021-12-25 15:45:35] [DEBUG]: WS接收到API调用: send_guild_channel_msg 参数: {"guild_id":"69327461639******","channel_id":"1769***","message":"你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别 人的梦 "} 
[2021-12-25 15:45:35] [DEBUG]: Protocol -> rev pkt: MsgProxy.SendMsg seq: 14166 
[2021-12-25 15:45:35] [INFO]: 处置WS命令时发生无法恢复的异常runtime error: invalid memory address or nil pointer dereference
goroutine 1886 [running]:
runtime/debug.Stack()
        runtime/debug/stack.go:24 +0x65
github.com/Mrs4s/go-cqhttp/server.(*wsConn).handleRequest.func1()
        github.com/Mrs4s/go-cqhttp/server/websocket.go:449 +0x45
panic({0xab57c0, 0x113e5a0})
        runtime/panic.go:1038 +0x215
github.com/Mrs4s/MiraiGo/client.(*GuildService).SendGuildChannelMessage(0xc0000b8780, 0xf64cf5842df2a0, 0x1b008d, 0xc0004f2680)
        github.com/Mrs4s/MiraiGo@v0.0.0-20211208080234-25c67a3ee1c1/client/guild_msg.go:88 +0x5d3
github.com/Mrs4s/go-cqhttp/coolq.(*CQBot).SendGuildChannelMessage(0xc00054a360, 0x1, 0x77, 0xc0004f2680)
        github.com/Mrs4s/go-cqhttp/coolq/bot.go:388 +0x11e
github.com/Mrs4s/go-cqhttp/coolq.(*CQBot).CQSendGuildChannelMessage(0xc00054a360, 0xf64cf5842df2a0, 0xc0003c4f20, {0x3, {0xc000726e6d, 0x79}, {0xc000726e6e, 0x77}, 0x0, 0x6d, ...}, ...)
        github.com/Mrs4s/go-cqhttp/coolq/api.go:707 +0x2d8
github.com/Mrs4s/go-cqhttp/modules/api.(*Caller).call(0xc00046a3e0, {0xc000726e0b, 0x16}, {0xc7aaa0, 0xc0004a6fa0})
        github.com/Mrs4s/go-cqhttp/modules/api/api.go:200 +0x7e4d
github.com/Mrs4s/go-cqhttp/modules/api.(*Caller).Call(0xc00046a3e0, {0xc000726e0b, 0x16}, {0xc7aaa0, 0xc0004a6fa0})
        github.com/Mrs4s/go-cqhttp/modules/api/caller.go:34 +0xaa
github.com/Mrs4s/go-cqhttp/server.(*wsConn).handleRequest(0xc00000c240, 0xc00054a360, {0xc000726e00, 0xe8, 0x65e})
        github.com/Mrs4s/go-cqhttp/server/websocket.go:456 +0x525
github.com/Mrs4s/go-cqhttp/server.(*websocketClient).listenAPI.func2(0xc000209800)
        github.com/Mrs4s/go-cqhttp/server/websocket.go:303 +0x95
created by github.com/Mrs4s/go-cqhttp/server.(*websocketClient).listenAPI
        github.com/Mrs4s/go-cqhttp/server/websocket.go:301 +0x1b2
 
[2021-12-25 15:45:35] [WARNING]: 监听反向WS Universal时出现错误: read tcp 127.0.0.1:44960->127.0.0.1:5003: use of closed network connection 
[2021-12-25 15:45:40] [DEBUG]: 向反向WS Universal服务器推送Event: {"interval":5000,"meta_event_type":"heartbeat","post_type":"meta_event","self_id":342431****,"status":{"app_enabled":true,"app_good":true,"app_initialized":true,"good":true,"online":true,"plugins_good":null,"stat":{"packet_received":382,"packet_sent":294,"packet_lost":0,"message_received":0,"message_sent":0,"disconnect_times":0,"lost_times":0,"last_message_time":0}},"time":1640418340}
 
[2021-12-25 15:45:40] [WARNING]: 向反向WS Universal服务器推送 Event 时出现错误: write tcp 127.0.0.1:44960->127.0.0.1:5003: use of closed network connection

补充说明(可选)

只要发送的内容中包含单数空格,就会导致这个问题,目前HTTPPOST和R-ws都无法正常发送
#1270也反馈了此错误,本issues说明了更详细的原因,以及提供更详细的错误信息

@oicv oicv added the bug? The issue author think this is a bug label Dec 25, 2021
@oicv
Copy link
Author

oicv commented Dec 25, 2021

#1270 也有着同样的问题

@oicv
Copy link
Author

oicv commented Dec 25, 2021

补充测试:发送QQ私聊消息提示OK,但是实际上无法收到所发送的内容(不会报错,但是消息也没收到)

@oicv oicv changed the title [Bug]: 发送中文消息中包含单数空格导致错误 [Bug]: 发送中文消息中包含单数空格或特殊字符会导致错误 Dec 25, 2021
@oicv
Copy link
Author

oicv commented Dec 25, 2021

经过进一步测试,以下情况会导致错误(注意:为了明确空格字符会将空格以[空格]进行表示单个空格)
你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别[空格]人的梦。
你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别[空格]人的梦[空格]
也就是说,哪怕空格是一对的,但是中文标点符号不是一对的,也会导致同样错误

@Mrs4s
Copy link
Owner

Mrs4s commented Dec 25, 2021

这个太奇怪了, 有空我会进一步测试

@oicv
Copy link
Author

oicv commented Dec 25, 2021

这个太奇怪了, 有空我会进一步测试

确实,我一开始以为是ws框架问题,但是经过测试后不论是httppost提交还是说是反向ws都有这个问题,不排除go语言导致的

@icarus-ai
Copy link

miraigo发上面那句话也失败了 协议本身哪里不对劲

@anye-star
Copy link

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。1
上面这行文本也是一个例子,甚至只要使一段字符串长度与其相同并包含中文字符即可触发。

@icarus-ai
Copy link

icarus-ai commented Dec 26, 2021

貌似40个2字节或者3字节的unicode+1个ASCII会发送失败

成功("y") // 1字节 0079 0079
失败("¡") // 2字节 00a1 c2a1
失败("ޙ") // 2字节 0799 de99
失败("ࠀ") // 3字节 0800 e0a080
失败("ঙ") // 3字节 0999 e0a699
成功("𐀀") // 4字节 10000 f0908080

@YuKi74
Copy link

YuKi74 commented Jan 18, 2022

会不会是处理消息长度的时候出的问题,当编码长度不同的字符混在一个字符串中的时候,我之前也出现过类似问题,把数据改成[]rune类型再判断长度就可以了。

只是一个猜测,仅供参考。

@oicv
Copy link
Author

oicv commented Jan 31, 2022

你站在桥上看风景看风景的人在楼上看你明月装饰了你的窗子你却装饰了别 人的梦

这个太统计了, 有空我会进一步测试

大佬几时可以看一下这个问题呢?这段时间触发这个问题太频繁了,使用起来有很多的问题

@oicv
Copy link
Author

oicv commented Feb 13, 2022

这个太奇怪了, 有空我会进一步测试

大佬,在最新版本中此问题仍旧存在

@Cloud-wish
Copy link

v1.0.0-rc1在Windows平台使用,也遇到了这个问题

@xianrui69
Copy link

这个太奇怪了, 有空我会进一步测试

找到问题了,换行空格相关的;
正常:“。。。。。。。。。。。。。。。。。。。\n。。。。。。。。。。。。。。。。。。。。。1”
发不出:“。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。1”
正常:“你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别人的梦。”
发不出:“你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别 人的梦。”

@xianrui69
Copy link

这个太奇怪了, 有空我会进一步测试

找到问题了,换行空格相关的; 正常:“。。。。。。。。。。。。。。。。。。。\n。。。。。。。。。。。。。。。。。。。。。1” 发不出:“。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。1” 正常:“你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别人的梦。” 发不出:“你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别 人的梦。”

应该是超过多少字符需要使用换行符,以及换行符前后不要有空格;我自己是换行符前面有空格所以发不出

@oicv
Copy link
Author

oicv commented Mar 15, 2022

这个太奇怪了, 有空我会进一步测试

找到问题了,换行空格相关的; 正常:“。。。。。。。。。。。。。。。。。。。\n。。。。。。。。。。。。。。。。。。。。。1” 发不出:“。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。1” 正常:“你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别人的梦。” 发不出:“你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你却装饰了别 人的梦。”

我测试是发现因为中文符合导致的,暂时的办法就是中文符号转英文,可能是中文符号长度导致的bug

@oicv
Copy link
Author

oicv commented Mar 15, 2022

如果内容是:你好,晴 天【发不出】
如果内容是:你好,晴 天【正常】

@xianrui69
Copy link

你好,晴天

我这边倒时都可以,用postman试了下

@xianrui69
Copy link

如果内容是:你好,晴天【发不出】 如果内容是:你好,晴天【正常】

基本可以肯定了 和排版有关,他应该默认传输的每行都塞得下,服务器没处理换行;一旦有一行异常了,就视作无效消息应该是;和显示有关

@xianrui69
Copy link

C}_@X{Y9CDS NRCJ 7KIQZJ

@LiShiwei18
Copy link

提供一些发送失败的样例,但是我无法总结出相关原因:

"2:vi.离开,起程 a.过去的,逝世的\n词源: 离开de-, 向下,离开。part, 分开,部分。即离开,分开。"
'n.长袍,上衣\n词源:robe袍服,礼袍词源同 rob,抢劫.代称,因过去衣服,特别是袍子是重要的战利品.'
'v.迫害\n词源:persecute 迫害per-,完全的,-sec,追求,跟随,词源同execute,sequence.引申词义追踪,猎捕,迫害.'
'n.(liter)升;公升(容量单位)\n词源:litre升来自拉丁libra,平衡,秤,用于液量单位升,词源同Libra,level.'

可用于帮助大家测试

@LiShiwei18
Copy link

似乎不能通过上述全部4个样例。可能不完全是回车前后有空格的问题

@fzls
Copy link
Contributor

fzls commented May 25, 2022

'n.(liter)升;公升(容量单位)\n词源:litre升来自拉丁libra,平衡,秤,用于液量单位升,词源同Libra,level.'

这几个测试用例好像把 \n 替换为 \r\n 就全部能正常发送了-。-但是前面的案例不清楚具体规则

@fzls
Copy link
Contributor

fzls commented May 25, 2022

似乎当消息长度为41,且其中的非中文字符为0或者1个时,必定出现该问题(上面 LiShiwei18 的那几个测试用例好像不属于这种)

下面的python脚本可以重现该流程-。-不清楚是腾讯服务器那边的问题,还是协议编码时的问题

“”“python
import string
import random

import requests

def Unicode():
val = random.randint(0x4e00, 0x9fbf)
return chr(val)

def English():
return random.choice(string.ascii_letters)

text = ''
cnt = 0
max_english_count = 1
for i in range(41):
p = random.randint(0, 1)
if p == 0 and cnt < max_english_count:
text += English()
cnt += 1
else:
text += Unicode()

print(text)
print(len(text))

access_token = "填入你的access_token"
group_id = "填入测试群组"
res = requests.post(f"https://localhost:5700/send_group_msg?access_token={access_token}", json={
"group_id": group_id,
"message": [
{'type': 'text', 'data': {'text': text}},
],
}, timeout=100)
print(f"发送消息结果 {res.status_code} {res.text}")

“””

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug? The issue author think this is a bug
Projects
None yet
Development

No branches or pull requests

10 participants