diff --git a/lib/std/zig/system/darwin.zig b/lib/std/zig/system/darwin.zig index 52abddc06a..fbddaa799a 100644 --- a/lib/std/zig/system/darwin.zig +++ b/lib/std/zig/system/darwin.zig @@ -87,6 +87,6 @@ pub const DarwinSDK = struct { } }; -test "" { +test { _ = macos; } diff --git a/src/AstGen.zig b/src/AstGen.zig index 522193d9a5..8bf1e190c7 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -3497,6 +3497,12 @@ fn fnDecl( const lib_name: u32 = if (fn_proto.lib_name) |lib_name_token| blk: { const lib_name_str = try astgen.strLitAsString(lib_name_token); + const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len]; + if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) { + return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{}); + } else if (lib_name_str.len == 0) { + return astgen.failTok(lib_name_token, "library name cannot be empty", .{}); + } break :blk lib_name_str.index; } else 0; @@ -3750,6 +3756,12 @@ fn globalVarDecl( const lib_name: u32 = if (var_decl.lib_name) |lib_name_token| blk: { const lib_name_str = try astgen.strLitAsString(lib_name_token); + const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len]; + if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) { + return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{}); + } else if (lib_name_str.len == 0) { + return astgen.failTok(lib_name_token, "library name cannot be empty", .{}); + } break :blk lib_name_str.index; } else 0; @@ -7239,6 +7251,12 @@ fn builtinCall( } const str_lit_token = main_tokens[operand_node]; const str = try astgen.strLitAsString(str_lit_token); + const str_slice = astgen.string_bytes.items[str.index..][0..str.len]; + if (mem.indexOfScalar(u8, str_slice, 0) != null) { + return astgen.failTok(str_lit_token, "import path cannot contain null bytes", .{}); + } else if (str.len == 0) { + return astgen.failTok(str_lit_token, "import path cannot be empty", .{}); + } const result = try gz.addStrTok(.import, str.index, str_lit_token); const gop = try astgen.imports.getOrPut(astgen.gpa, str.index); if (!gop.found_existing) { @@ -9260,6 +9278,11 @@ fn identifierTokenString(astgen: *AstGen, token: Ast.TokenIndex) InnerError![]co var buf: ArrayListUnmanaged(u8) = .{}; defer buf.deinit(astgen.gpa); try astgen.parseStrLit(token, &buf, ident_name, 1); + if (mem.indexOfScalar(u8, buf.items, 0) != null) { + return astgen.failTok(token, "identifier cannot contain null bytes", .{}); + } else if (buf.items.len == 0) { + return astgen.failTok(token, "identifier cannot be empty", .{}); + } const duped = try astgen.arena.dupe(u8, buf.items); return duped; } @@ -9279,7 +9302,14 @@ fn appendIdentStr( if (!mem.startsWith(u8, ident_name, "@")) { return buf.appendSlice(astgen.gpa, ident_name); } else { - return astgen.parseStrLit(token, buf, ident_name, 1); + const start = buf.items.len; + try astgen.parseStrLit(token, buf, ident_name, 1); + const slice = buf.items[start..]; + if (mem.indexOfScalar(u8, slice, 0) != null) { + return astgen.failTok(token, "identifier cannot contain null bytes", .{}); + } else if (slice.len == 0) { + return astgen.failTok(token, "identifier cannot be empty", .{}); + } } } @@ -9723,6 +9753,12 @@ fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 { const token_bytes = astgen.tree.tokenSlice(str_lit_token); try string_bytes.append(gpa, 0); // Indicates this is a test. try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0); + const slice = string_bytes.items[str_index + 1 ..]; + if (mem.indexOfScalar(u8, slice, 0) != null) { + return astgen.failTok(str_lit_token, "test name cannot contain null bytes", .{}); + } else if (slice.len == 0) { + return astgen.failTok(str_lit_token, "empty test name must be omitted", .{}); + } try string_bytes.append(gpa, 0); return str_index; } diff --git a/test/cases/compile_errors/invalid_identifiers.zig b/test/cases/compile_errors/invalid_identifiers.zig new file mode 100644 index 0000000000..bf1244b547 --- /dev/null +++ b/test/cases/compile_errors/invalid_identifiers.zig @@ -0,0 +1,33 @@ +extern "" var a: u32; +extern "" fn b() void; + +extern "\x00" var c: u32; +extern "\x00" fn d() void; + +test "" {} +test "\x00" {} + +const e = @import(""); +const f = @import("\x00"); + +comptime { + const @"" = undefined; +} +comptime { + const @"\x00" = undefined; +} + +// error +// backend=stage2 +// target=native +// +// :1:8: error: library name cannot be empty +// :2:8: error: library name cannot be empty +// :4:8: error: library name cannot contain null bytes +// :5:8: error: library name cannot contain null bytes +// :7:6: error: empty test name must be omitted +// :8:6: error: test name cannot contain null bytes +// :10:19: error: import path cannot be empty +// :11:19: error: import path cannot contain null bytes +// :14:11: error: identifier cannot be empty +// :17:11: error: identifier cannot contain null bytes diff --git a/test/cases/compile_errors/stage1/obj/wrong_panic_signature_runtime_function.zig b/test/cases/compile_errors/stage1/obj/wrong_panic_signature_runtime_function.zig index 5cf224c4a8..049becaeb1 100644 --- a/test/cases/compile_errors/stage1/obj/wrong_panic_signature_runtime_function.zig +++ b/test/cases/compile_errors/stage1/obj/wrong_panic_signature_runtime_function.zig @@ -1,4 +1,4 @@ -test "" {} +test {} pub fn panic() void {} diff --git a/test/standalone/issue_9812/main.zig b/test/standalone/issue_9812/main.zig index 70899c9326..118e8b6d77 100644 --- a/test/standalone/issue_9812/main.zig +++ b/test/standalone/issue_9812/main.zig @@ -14,7 +14,7 @@ const Error = error{ InvalidCmdLine, }; -test "" { +test { const allocator = std.heap.c_allocator; const args = try std.process.argsAlloc(allocator);