fix(host): _read_loop 跳过非 dict params 等脏消息,不杀死读循环
顶层为 dict 但 params 为真值非 dict 时,旧代码在 params.get 处抛
AttributeError,被外层 except 吞掉、读线程退出,后续正常消息
再也送达不了。改后校验跳过并记 stderr 日志、脏消息不进 events、
读循环继续;None/缺失/假值沿用旧 or {} 语义。审计同函数其它
get 路径:一并守住不可哈希的响应 id(pending.get)与 threadId /
thread.id(turn_queues.get)的 TypeError 致死路径;params.thread
已有 isinstance 守卫、_append_trace 已有 try 包裹,均不动。
This commit is contained in:
1 parent
fddd08546d
commit
24adb568da
2 files changed
+186
-1
No files matched your search
@@ -504,16 +504,57 @@ class Server:
|
||||
self._answer_server_request(msg)
|
||||
continue
|
||||
if "id" in msg:
|
||||
mid = msg["id"]
|
||||
if isinstance(mid, (list, dict)):
|
||||
# id 在此被当 pending 字典的 key:不可哈希时
|
||||
# 旧代码在 pending.get 处抛 TypeError,被外层
|
||||
# except 吞掉、读线程退出。这类 id 本就不可能
|
||||
# 命中 pending(key 全是 request 发出的 int),
|
||||
# 跳过本条、读循环继续。
|
||||
sys.stderr.write(
|
||||
"host _read_loop: skip response with "
|
||||
"unhashable id type=%s value=%.200s\n"
|
||||
% (type(mid).__name__, repr(mid)))
|
||||
sys.stderr.flush()
|
||||
continue
|
||||
with self.pending_lock:
|
||||
q = self.pending.get(msg["id"])
|
||||
q = self.pending.get(mid)
|
||||
if q is not None:
|
||||
q.put(msg)
|
||||
continue
|
||||
# 通知
|
||||
params = msg.get("params") or {}
|
||||
if not isinstance(params, dict):
|
||||
# 残留项:params 为真值非 dict(如 "foo"/123/
|
||||
# [1,2]/True)时旧代码在下一行 params.get 抛
|
||||
# AttributeError,被外层 except 吞掉、读线程退出,
|
||||
# 后续正常消息再也送达不了。脏消息跳过、不进
|
||||
# events、不当正常请求处理,读循环继续。
|
||||
# None/缺失/假值沿用旧的 `or {}` 语义(已是
|
||||
# dict,不走此分支),正常消息语义不动。
|
||||
sys.stderr.write(
|
||||
"host _read_loop: skip notification with "
|
||||
"non-dict params type=%s value=%.200s\n"
|
||||
% (type(params).__name__, repr(params)))
|
||||
sys.stderr.flush()
|
||||
continue
|
||||
thread_id = params.get("threadId")
|
||||
if not thread_id and isinstance(params.get("thread"), dict):
|
||||
thread_id = params["thread"].get("id")
|
||||
if not isinstance(thread_id, str) and thread_id is not None:
|
||||
# thread_id 只用于 turn_queues 路由:不可哈希的
|
||||
# 值(如 list/dict)旧代码在 turn_queues.get 处
|
||||
# 抛 TypeError 杀死读线程;非 str 的 key 本就不
|
||||
# 可能命中 turn_queues(key 全是 str),一律视为
|
||||
# 不可路由,事件本身仍保留、只跳过路由。
|
||||
if isinstance(thread_id, (list, dict)):
|
||||
sys.stderr.write(
|
||||
"host _read_loop: skip turn routing with "
|
||||
"unhashable thread_id type=%s value=%.200s\n"
|
||||
% (type(thread_id).__name__,
|
||||
repr(thread_id)))
|
||||
sys.stderr.flush()
|
||||
thread_id = None
|
||||
with self.events_lock:
|
||||
self.events.append(msg)
|
||||
if self.trace_path is not None:
|
||||
|
||||
Reference in new issue
Block a user