authorgravatar for wrongnull@gmail.comBogdan Romanyuk <wrongnull@gmail.com> 2024-07-22 02:56:04+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-21 23:56:04+00:00
log42d9017feb0fe731961f5f7b1242ad12644a5074
tree953d53346c69af528e071e7f9b8bb2db9c8aa396
parent08cddaf11c7bac5fba2e696ed6b99d1f7b730543
signaturebadge-check Signed by PGP key B5690EEEBB952194

Sema: fix OOB access in coerceTupleToStruct (#19620)

Co-authored-by: Veikka Tuominen <git@vexu.eu>

2 files changed, 18 insertions(+), 23 deletions(-)

src/Sema.zig+5-23
......@@ -31867,14 +31867,9 @@ fn coerceTupleToStruct(
3186731867 };
3186831868 for (0..field_count) |tuple_field_index| {
3186931869 const field_src = inst_src; // TODO better source location
31870 const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
31871 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
31872 anon_struct_type.names.get(ip)[tuple_field_index]
31873 else
31874 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{tuple_field_index}, .no_embedded_nulls),
31875 .struct_type => ip.loadStructType(inst_ty.toIntern()).field_names.get(ip)[tuple_field_index],
31876 else => unreachable,
31877 };
31870 const field_name = inst_ty.structFieldName(tuple_field_index, mod).unwrap() orelse
31871 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{tuple_field_index}, .no_embedded_nulls);
31872
3187831873 const struct_field_index = try sema.structFieldIndex(block, struct_ty, field_name, field_src);
3187931874 const struct_field_ty = Type.fromInterned(struct_type.field_types.get(ip)[struct_field_index]);
3188031875 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, @intCast(tuple_field_index));
......@@ -31980,21 +31975,8 @@ fn coerceTupleToTuple(
3198031975 for (0..dest_field_count) |field_index_usize| {
3198131976 const field_i: u32 = @intCast(field_index_usize);
3198231977 const field_src = inst_src; // TODO better source location
31983 const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
31984 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
31985 anon_struct_type.names.get(ip)[field_i]
31986 else
31987 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_i}, .no_embedded_nulls),
31988 .struct_type => s: {
31989 const struct_type = ip.loadStructType(inst_ty.toIntern());
31990 if (struct_type.field_names.len > 0) {
31991 break :s struct_type.field_names.get(ip)[field_i];
31992 } else {
31993 break :s try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_i}, .no_embedded_nulls);
31994 }
31995 },
31996 else => unreachable,
31997 };
31978 const field_name = inst_ty.structFieldName(field_index_usize, mod).unwrap() orelse
31979 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_index_usize}, .no_embedded_nulls);
3199831980
3199931981 if (field_name.eqlSlice("len", ip))
3200031982 return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{});
test/cases/compile_errors/invalid_tuple_to_struct_coercion.zig created+13
......@@ -0,0 +1,13 @@
1const S = struct {
2 fizz: void,
3};
4
5export fn entry() void {
6 _ = @as(S, struct { void }{{}});
7}
8
9// error
10// target=native
11//
12// :6:31: error: no field named '0' in struct 'tmp.S'
13// :1:11: note: struct declared here