authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-25 21:25:09+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-26 12:14:59+03:00
loga463dc7d6c3bb560903d11cb9e34668e89c374d6
tree70fa3aee76ed184ad30de65959aa39583cea4316
parent2f54129087859fbd9a437d0cee33f16df523dd0b

AstGen: disable null bytes and empty stings in some places

Namely: * test names * identifiers * library names * import strings

5 files changed, 73 insertions(+), 4 deletions(-)

lib/std/zig/system/darwin.zig+1-1
...@@ -87,6 +87,6 @@ pub const DarwinSDK = struct {...@@ -87,6 +87,6 @@ pub const DarwinSDK = struct {
87 }87 }
88};88};
8989
90test "" {90test {
91 _ = macos;91 _ = macos;
92}92}
src/AstGen.zig+37-1
...@@ -3497,6 +3497,12 @@ fn fnDecl(...@@ -3497,6 +3497,12 @@ fn fnDecl(
34973497
3498 const lib_name: u32 = if (fn_proto.lib_name) |lib_name_token| blk: {3498 const lib_name: u32 = if (fn_proto.lib_name) |lib_name_token| blk: {
3499 const lib_name_str = try astgen.strLitAsString(lib_name_token);3499 const lib_name_str = try astgen.strLitAsString(lib_name_token);
3500 const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len];
3501 if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) {
3502 return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{});
3503 } else if (lib_name_str.len == 0) {
3504 return astgen.failTok(lib_name_token, "library name cannot be empty", .{});
3505 }
3500 break :blk lib_name_str.index;3506 break :blk lib_name_str.index;
3501 } else 0;3507 } else 0;
35023508
...@@ -3750,6 +3756,12 @@ fn globalVarDecl(...@@ -3750,6 +3756,12 @@ fn globalVarDecl(
37503756
3751 const lib_name: u32 = if (var_decl.lib_name) |lib_name_token| blk: {3757 const lib_name: u32 = if (var_decl.lib_name) |lib_name_token| blk: {
3752 const lib_name_str = try astgen.strLitAsString(lib_name_token);3758 const lib_name_str = try astgen.strLitAsString(lib_name_token);
3759 const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len];
3760 if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) {
3761 return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{});
3762 } else if (lib_name_str.len == 0) {
3763 return astgen.failTok(lib_name_token, "library name cannot be empty", .{});
3764 }
3753 break :blk lib_name_str.index;3765 break :blk lib_name_str.index;
3754 } else 0;3766 } else 0;
37553767
...@@ -7239,6 +7251,12 @@ fn builtinCall(...@@ -7239,6 +7251,12 @@ fn builtinCall(
7239 }7251 }
7240 const str_lit_token = main_tokens[operand_node];7252 const str_lit_token = main_tokens[operand_node];
7241 const str = try astgen.strLitAsString(str_lit_token);7253 const str = try astgen.strLitAsString(str_lit_token);
7254 const str_slice = astgen.string_bytes.items[str.index..][0..str.len];
7255 if (mem.indexOfScalar(u8, str_slice, 0) != null) {
7256 return astgen.failTok(str_lit_token, "import path cannot contain null bytes", .{});
7257 } else if (str.len == 0) {
7258 return astgen.failTok(str_lit_token, "import path cannot be empty", .{});
7259 }
7242 const result = try gz.addStrTok(.import, str.index, str_lit_token);7260 const result = try gz.addStrTok(.import, str.index, str_lit_token);
7243 const gop = try astgen.imports.getOrPut(astgen.gpa, str.index);7261 const gop = try astgen.imports.getOrPut(astgen.gpa, str.index);
7244 if (!gop.found_existing) {7262 if (!gop.found_existing) {
...@@ -9260,6 +9278,11 @@ fn identifierTokenString(astgen: *AstGen, token: Ast.TokenIndex) InnerError![]co...@@ -9260,6 +9278,11 @@ fn identifierTokenString(astgen: *AstGen, token: Ast.TokenIndex) InnerError![]co
9260 var buf: ArrayListUnmanaged(u8) = .{};9278 var buf: ArrayListUnmanaged(u8) = .{};
9261 defer buf.deinit(astgen.gpa);9279 defer buf.deinit(astgen.gpa);
9262 try astgen.parseStrLit(token, &buf, ident_name, 1);9280 try astgen.parseStrLit(token, &buf, ident_name, 1);
9281 if (mem.indexOfScalar(u8, buf.items, 0) != null) {
9282 return astgen.failTok(token, "identifier cannot contain null bytes", .{});
9283 } else if (buf.items.len == 0) {
9284 return astgen.failTok(token, "identifier cannot be empty", .{});
9285 }
9263 const duped = try astgen.arena.dupe(u8, buf.items);9286 const duped = try astgen.arena.dupe(u8, buf.items);
9264 return duped;9287 return duped;
9265}9288}
...@@ -9279,7 +9302,14 @@ fn appendIdentStr(...@@ -9279,7 +9302,14 @@ fn appendIdentStr(
9279 if (!mem.startsWith(u8, ident_name, "@")) {9302 if (!mem.startsWith(u8, ident_name, "@")) {
9280 return buf.appendSlice(astgen.gpa, ident_name);9303 return buf.appendSlice(astgen.gpa, ident_name);
9281 } else {9304 } else {
9282 return astgen.parseStrLit(token, buf, ident_name, 1);9305 const start = buf.items.len;
9306 try astgen.parseStrLit(token, buf, ident_name, 1);
9307 const slice = buf.items[start..];
9308 if (mem.indexOfScalar(u8, slice, 0) != null) {
9309 return astgen.failTok(token, "identifier cannot contain null bytes", .{});
9310 } else if (slice.len == 0) {
9311 return astgen.failTok(token, "identifier cannot be empty", .{});
9312 }
9283 }9313 }
9284}9314}
92859315
...@@ -9723,6 +9753,12 @@ fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {...@@ -9723,6 +9753,12 @@ fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {
9723 const token_bytes = astgen.tree.tokenSlice(str_lit_token);9753 const token_bytes = astgen.tree.tokenSlice(str_lit_token);
9724 try string_bytes.append(gpa, 0); // Indicates this is a test.9754 try string_bytes.append(gpa, 0); // Indicates this is a test.
9725 try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0);9755 try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0);
9756 const slice = string_bytes.items[str_index + 1 ..];
9757 if (mem.indexOfScalar(u8, slice, 0) != null) {
9758 return astgen.failTok(str_lit_token, "test name cannot contain null bytes", .{});
9759 } else if (slice.len == 0) {
9760 return astgen.failTok(str_lit_token, "empty test name must be omitted", .{});
9761 }
9726 try string_bytes.append(gpa, 0);9762 try string_bytes.append(gpa, 0);
9727 return str_index;9763 return str_index;
9728}9764}
test/cases/compile_errors/invalid_identifiers.zig created+33
...@@ -0,0 +1,33 @@
1extern "" var a: u32;
2extern "" fn b() void;
3
4extern "\x00" var c: u32;
5extern "\x00" fn d() void;
6
7test "" {}
8test "\x00" {}
9
10const e = @import("");
11const f = @import("\x00");
12
13comptime {
14 const @"" = undefined;
15}
16comptime {
17 const @"\x00" = undefined;
18}
19
20// error
21// backend=stage2
22// target=native
23//
24// :1:8: error: library name cannot be empty
25// :2:8: error: library name cannot be empty
26// :4:8: error: library name cannot contain null bytes
27// :5:8: error: library name cannot contain null bytes
28// :7:6: error: empty test name must be omitted
29// :8:6: error: test name cannot contain null bytes
30// :10:19: error: import path cannot be empty
31// :11:19: error: import path cannot contain null bytes
32// :14:11: error: identifier cannot be empty
33// :17:11: error: identifier cannot contain null bytes
test/cases/compile_errors/stage1/obj/wrong_panic_signature_runtime_function.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1test "" {}1test {}
22
3pub fn panic() void {}3pub fn panic() void {}
44
test/standalone/issue_9812/main.zig+1-1
...@@ -14,7 +14,7 @@ const Error = error{...@@ -14,7 +14,7 @@ const Error = error{
14 InvalidCmdLine,14 InvalidCmdLine,
15};15};
1616
17test "" {17test {
18 const allocator = std.heap.c_allocator;18 const allocator = std.heap.c_allocator;
1919
20 const args = try std.process.argsAlloc(allocator);20 const args = try std.process.argsAlloc(allocator);