From a9a53bd11794eaa575b291921e6904c8931c1935 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 15 Sep 2026 22:45:29 +0800 Subject: [PATCH] =?UTF-8?q?fix(withcontent):=20=5Ffind=5Fprovider=20?= =?UTF-8?q?=E5=80=92=E5=BA=8F=E5=BE=AA=E7=8E=AF=E4=B8=8A=E7=95=8C=E6=98=BE?= =?UTF-8?q?=E5=BC=8F=E8=BD=AC=E6=9C=89=E7=AC=A6=E5=8F=B7=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E8=A2=AB=E6=97=A0=E7=AC=A6=E5=8F=B7=E5=8C=96=E5=90=8E?= =?UTF-8?q?=E9=80=80=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit range(stack.top - 1, -1, -1) 中 stack.top 是 UINT64 字段,上界被推断为无符号时该递减循环的谓词退化为 ugt(-1 在无符号域即 UINT32_MAX) => 条件恒假、循环体不可达、_find_provider 恒返回 NULL,with 的 __mbuddy__ 注入失效(_str.upper 对 NULL 取 vtable 崩溃) 显式 t.CInt 转换使符号域与递减语义一致,与编译器侧 stop 为负字面量时退回有符号谓词的修复互为双保险 --- _withcontent.vp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/_withcontent.vp b/_withcontent.vp index 4bd7bd7..1dd1590 100644 --- a/_withcontent.vp +++ b/_withcontent.vp @@ -66,7 +66,12 @@ def _find_provider(field_name: str) -> t.CPtr: """Search for matching field_name starting from stack top. Return associated pointer, or NULL if no match found.""" stack: _ProviderStack | t.CPtr = _get_stack() - for i in range(stack.top - 1, -1, -1): + # 上界显式转 t.CInt(有符号):本循环是「递减 + stop 为 -1」形态,若上界 + # 被当作无符号(stack.top 是 UINT64 字段),比较谓词会退化为 ugt,而 -1 在 + # 无符号域是 UINT32_MAX ⇒ 条件恒假、循环体不可达、本函数恒返回 NULL(with 的 + # __mbuddy__ 注入全部失效,_str.upper 对 NULL 取 vtable 崩溃)。显式转换让 + # 符号域与递减语义一致,与编译器侧「stop 为负字面量时退回有符号谓词」互为双保险。 + for i in range(t.CInt(stack.top) - 1, -1, -1): # 字段名用 strcmp 内容比较:编译器对每次 create_global_string 生成 # 独立的字符串常量(TPV 不去重),push/find 的指针地址不同, # 指针 == 永假会导致 provider 匹配失败(__mbuddy__ 注入不上)。