authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-21 01:47:54-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-03-21 01:47:54-07:00
logb5cef9e8b48e81fb1f3b56cb752bac95e6a2d44b
tree40bf026cca4014c3d7502cd70f832ea807a3d0e9
parente831313b10c8c0f6c1984bb1704f3ca90105c416
parent4d5e0a0434a69059f623e5c51862fb1a2c553abc
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19374 from ziglang/slice-by-len-safety

add OOB safety check for by-length slice of array

2 files changed, 30 insertions(+), 6 deletions(-)

src/Sema.zig+10-6
...@@ -33284,12 +33284,16 @@ fn analyzeSlice(...@@ -33284,12 +33284,16 @@ fn analyzeSlice(
33284 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);33284 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
33285 }33285 }
3328633286
33287 if (slice_ty.isSlice(mod)) {33287 bounds_check: {
33288 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);33288 const actual_len = if (array_ty.zigTypeTag(mod) == .Array)
33289 const actual_len = if (slice_ty.sentinel(mod) == null)33289 try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))
33290 slice_len_inst33290 else if (slice_ty.isSlice(mod)) l: {
33291 else33291 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
33292 try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true);33292 break :l if (slice_ty.sentinel(mod) == null)
33293 slice_len_inst
33294 else
33295 try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true);
33296 } else break :bounds_check;
3329333297
33294 const actual_end = if (slice_sentinel != null)33298 const actual_end = if (slice_sentinel != null)
33295 try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true)33299 try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true)
test/cases/safety/out of bounds array slice by length.zig created+20
...@@ -0,0 +1,20 @@
1const std = @import("std");
2
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
4 _ = stack_trace;
5 if (std.mem.eql(u8, message, "index out of bounds: index 16, len 5")) {
6 std.process.exit(0);
7 }
8 std.process.exit(1);
9}
10pub fn main() !void {
11 var buf: [5]u8 = undefined;
12 _ = buf[foo(6)..][0..10];
13 return error.TestFailed;
14}
15fn foo(a: u32) u32 {
16 return a;
17}
18// run
19// backend=llvm
20// target=native