From 8445af93d2399a2a52d9d9f01f87ab92668a6a1b Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 28 Aug 2026 15:06:30 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpv):=20=E6=B3=9B=E5=9E=8B=E6=B1=A1?= =?UTF-8?q?=E6=9F=93=E6=A3=80=E6=B5=8B=E6=94=B9=20token=20=E8=BE=B9?= =?UTF-8?q?=E7=95=8C=E5=8C=B9=E9=85=8D=EF=BC=88=E6=A0=B9=E6=B2=BB=20strstr?= =?UTF-8?q?=20=E8=AF=AF=E6=9D=80=E5=90=88=E6=B3=95=E7=89=B9=E5=8C=96?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _list.vp L57 elem_ptr: T | t.CPtr 在 list[AST|t.CPtr] 特化时被误报污染:strstr('e9dfb296a8674aee.AST|t.CPtr', 'T') 把 AST 内部字符 T 当参数名 - 新增 _str_contains_ident:独立标识符检测(两侧非字母/数字/_),实参内部字符不算污染 - T→T 完全自映射仍直接报错(明确污染);子串场景按边界判定 --- App/lib/core/Gen/Type/TypeGenResolve.vp | 44 ++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index d187936..24f27fe 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -310,6 +310,42 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return res_c # ---- 6. 查不到:保持原样 ---- return type_name + + def _str_contains_ident(self, s: str, ident: str) -> int: + """检查 s 中是否包含独立标识符 ident(两侧非字母/数字/下划线) + + 用于泛型实参污染检测:单字符参数名(如 'T')在实参串 "AST|t.CPtr" + 中作为 AST/CPtr 内部字符出现时不算污染——必须两侧是边界 + (空格/|/[/]/,等)才算独立标识符。strstr 子串匹配会把实参内部 + 的 'T' 误判为参数名 → 合法特化 list[AST|t.CPtr] 被误杀。 + """ + if s is None or ident is None or ident[0] == '\0': + return 0 + s_len: t.CSizeT = string.strlen(s) + id_len: t.CSizeT = string.strlen(ident) + if id_len == 0 or s_len < id_len: + return 0 + i: t.CSizeT + for i in range(s_len - id_len + 1): + if string.strncmp(s + i, ident, id_len) != 0: + continue + # 左边界:i==0 或前一字符非标识符字符 + left_ok: int = 1 + if i > 0: + lc: t.CChar = s[i - 1] + if (lc >= 'a' and lc <= 'z') or (lc >= 'A' and lc <= 'Z') \ + or (lc >= '0' and lc <= '9') or lc == '_': + left_ok = 0 + right_ok: int = 1 + if i + id_len < s_len: + rc: t.CChar = s[i + id_len] + if (rc >= 'a' and rc <= 'z') or (rc >= 'A' and rc <= 'Z') \ + or (rc >= '0' and rc <= '9') or rc == '_': + right_ok = 0 + if left_ok != 0 and right_ok != 0: + return 1 + return 0 + def _parse_type_string(self, pool: memhub.MemBuddy | t.CPtr, type_str: str, ctx: t.CInt) -> ast.AST | t.CPtr: @@ -1265,7 +1301,13 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): gp_j: t.CSizeT for gp_j in range(gp_n): gp_pn: str = tpn_g.get(gp_j) - if gp_pn is not None and string.strstr(gp_ta, gp_pn) is not None: + # token 边界匹配(非 strstr 子串):实参串中必须出现 + # "独立标识符"参数名(两侧非字母/数字/_)。否则 strstr + # 把实参内部字符误判为参数名——"e9dfb296a8674aee.AST| + # t.CPtr" 含 'T' 字符但 T 在 AST/CPtr 内部不是独立 + # 参数名 → 合法特化 list[AST|t.CPtr] 被误杀(_list.vp + # L57 elem_ptr: T | t.CPtr 根因)。 + if gp_pn is not None and self._str_contains_ident(gp_ta, gp_pn) != 0: polluted = 1 break if polluted != 0: