fix: 全面代码审查 — 修复 3 CRITICAL + 4 HIGH 问题

CRITICAL:
- parser: 6处栈数组加边界检查 (struct_init/decl/block/params/functions/structs)
- codegen: return前跳过返回值alloca防止use-after-free
- ast: NEW宏加NULL检查防止arena耗尽崩溃

HIGH:
- main: shell元字符过滤防命令注入
- codegen: LLVMContext泄漏修复 (out_context参数)
- codegen: f64隐式return用LLVMConstReal替代LLVMConstInt
- sema: 返回类型与函数声明校验

其他:
- parser/codegen: 递归深度限制1000层
- codegen: struct值类型不追踪cleanup (栈上数据不能free)

基于三份审查报告 (架构/code quality/安全) 修复。
This commit is contained in:
2026-06-05 13:05:27 +08:00
parent 1d4fb27170
commit af0725caca
7 changed files with 90 additions and 17 deletions
+15
View File
@@ -2,6 +2,8 @@
#include <string.h>
// === 类型关系 ===
static TypeKind current_return_type = TYPE_VOID;
static TypeKind promote(TypeKind a, TypeKind b) {
if (a == TYPE_F64 || b == TYPE_F64) return TYPE_F64;
if (a == TYPE_I64 || b == TYPE_I64) return TYPE_I64;
@@ -303,7 +305,10 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
AstNode* p = node->as.function.params[i];
scope_insert(fn_scope, a, p->as.parameter.name, SYM_PARAMETER, p->as.parameter.type);
}
TypeKind saved = current_return_type;
current_return_type = node->as.function.return_type;
analyze_node(node->as.function.body, fn_scope, errors, a);
current_return_type = saved;
break;
}
@@ -427,6 +432,16 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
if (node->as.return_stmt.expr) {
analyze_expr(node->as.return_stmt.expr, scope, errors, a);
node->type.kind = node->as.return_stmt.expr->type.kind;
TypeKind actual = node->as.return_stmt.expr->type.kind;
TypeKind expected = current_return_type;
if (actual != TYPE_ERROR && expected != TYPE_VOID && actual != expected) {
error_add(errors, "<sema>", node->line, node->col,
"返回类型不匹配: 期望 '%s',得到 '%s'",
type_name(expected), type_name(actual));
}
} else if (current_return_type != TYPE_VOID) {
error_add(errors, "<sema>", node->line, node->col,
"函数应返回值类型 '%s'", type_name(current_return_type));
}
break;