Skip to content

Commit d0c9fd0

Browse files
authored
Merge branch 'master' into feat-remove-raw-overflows
2 parents 51a69d8 + b0dba46 commit d0c9fd0

36 files changed

+929
-140
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ if("${ZIG_VERSION}" STREQUAL "")
4545
find_program(GIT_EXE NAMES git NAMES_PER_DIR)
4646
if(GIT_EXE)
4747
execute_process(
48-
COMMAND ${GIT_EXE} -C ${CMAKE_SOURCE_DIR} describe --match *.*.* --tags
48+
COMMAND ${GIT_EXE} -C ${CMAKE_SOURCE_DIR} describe --match *.*.* --tags --abbrev=9
4949
RESULT_VARIABLE EXIT_STATUS
5050
OUTPUT_VARIABLE GIT_DESCRIBE
5151
OUTPUT_STRIP_TRAILING_WHITESPACE

bootstrap.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ static const char *get_host_os(void) {
6060
return "macos";
6161
#elif defined(__linux__)
6262
return "linux";
63+
#elif defined(__FreeBSD__)
64+
return "freebsd";
6365
#else
6466
#error TODO implement get_host_os in this build script for this target
6567
#endif

build.zig

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,14 @@ pub fn build(b: *std.Build) !void {
263263

264264
var code: u8 = undefined;
265265
const git_describe_untrimmed = b.runAllowFail(&[_][]const u8{
266-
"git", "-C", b.build_root.path orelse ".", "describe", "--match", "*.*.*", "--tags",
266+
"git",
267+
"-C",
268+
b.build_root.path orelse ".",
269+
"describe",
270+
"--match",
271+
"*.*.*",
272+
"--tags",
273+
"--abbrev=9",
267274
}, &code, .Ignore) catch {
268275
break :v version_string;
269276
};

ci/aarch64-linux-debug.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ export PATH="$HOME/deps/wasmtime-v2.0.2-$ARCH-linux:$PATH"
1616

1717
# Make the `zig version` number consistent.
1818
# This will affect the cmake command below.
19-
git config core.abbrev 9
2019
git fetch --unshallow || true
2120
git fetch --tags
2221

ci/aarch64-linux-release.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ export PATH="$HOME/deps/wasmtime-v2.0.2-$ARCH-linux:$PATH"
1616

1717
# Make the `zig version` number consistent.
1818
# This will affect the cmake command below.
19-
git config core.abbrev 9
2019
git fetch --unshallow || true
2120
git fetch --tags
2221

ci/aarch64-macos-debug.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ cd $ZIGDIR
1717

1818
# Make the `zig version` number consistent.
1919
# This will affect the cmake command below.
20-
git config core.abbrev 9
2120
git fetch --unshallow || true
2221
git fetch --tags
2322

ci/aarch64-macos-release.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ cd $ZIGDIR
1717

1818
# Make the `zig version` number consistent.
1919
# This will affect the cmake command below.
20-
git config core.abbrev 9
2120
git fetch --unshallow || true
2221
git fetch --tags
2322

ci/aarch64-windows.ps1

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ function CheckLastExitCode {
2424

2525
# Make the `zig version` number consistent.
2626
# This will affect the `zig build` command below which uses `git describe`.
27-
git config core.abbrev 9
2827
git fetch --tags
2928

3029
if ((git rev-parse --is-shallow-repository) -eq "true") {

ci/x86_64-linux-debug.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ export PATH="$HOME/deps/wasmtime-v2.0.2-$ARCH-linux:$HOME/deps/qemu-linux-x86_64
1616

1717
# Make the `zig version` number consistent.
1818
# This will affect the cmake command below.
19-
git config core.abbrev 9
2019
git fetch --unshallow || true
2120
git fetch --tags
2221

ci/x86_64-linux-release.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ export PATH="$HOME/deps/wasmtime-v2.0.2-$ARCH-linux:$HOME/deps/qemu-linux-x86_64
1616

1717
# Make the `zig version` number consistent.
1818
# This will affect the cmake command below.
19-
git config core.abbrev 9
2019
git fetch --unshallow || true
2120
git fetch --tags
2221

ci/x86_64-macos-release.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ cd $ZIGDIR
2222

2323
# Make the `zig version` number consistent.
2424
# This will affect the cmake command below.
25-
git config core.abbrev 9
2625
git fetch --unshallow || true
2726
git fetch --tags
2827

ci/x86_64-windows-debug.ps1

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ function CheckLastExitCode {
2323

2424
# Make the `zig version` number consistent.
2525
# This will affect the `zig build` command below which uses `git describe`.
26-
git config core.abbrev 9
2726
git fetch --tags
2827

2928
if ((git rev-parse --is-shallow-repository) -eq "true") {

ci/x86_64-windows-release.ps1

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ function CheckLastExitCode {
2323

2424
# Make the `zig version` number consistent.
2525
# This will affect the `zig build` command below which uses `git describe`.
26-
git config core.abbrev 9
2726
git fetch --tags
2827

2928
if ((git rev-parse --is-shallow-repository) -eq "true") {

doc/build.zig.zon.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ This is computed from the file contents of the directory of files that is
5151
obtained after fetching `url` and applying the inclusion rules given by
5252
`paths`.
5353

54-
This field is the source of truth; packages do not come from an `url`; they
54+
This field is the source of truth; packages do not come from a `url`; they
5555
come from a `hash`. `url` is just one of many possible mirrors for how to
5656
obtain a package matching this `hash`.
5757

lib/init/build.zig.zon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// Each dependency must either provide a `url` and `hash`, or a `path`.
1414
// `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
1515
// Once all dependencies are fetched, `zig build` no longer requires
16-
// Internet connectivity.
16+
// internet connectivity.
1717
.dependencies = .{
1818
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
1919
//.example = .{
@@ -26,7 +26,7 @@
2626
// // obtained after fetching `url` and applying the inclusion rules given by
2727
// // `paths`.
2828
// //
29-
// // This field is the source of truth; packages do not come from an `url`; they
29+
// // This field is the source of truth; packages do not come from a `url`; they
3030
// // come from a `hash`. `url` is just one of many possible mirrors for how to
3131
// // obtain a package matching this `hash`.
3232
// //

lib/std/Build/Step/Compile.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ kind: Kind,
3737
major_only_filename: ?[]const u8,
3838
name_only_filename: ?[]const u8,
3939
strip: ?bool,
40+
formatted_panics: ?bool = null,
4041
unwind_tables: ?bool,
4142
// keep in sync with src/link.zig:CompressDebugSections
4243
compress_debug_sections: enum { none, zlib, zstd } = .none,
@@ -1702,6 +1703,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
17021703
if (self.generated_h != null) try zig_args.append("-femit-h");
17031704

17041705
try addFlag(&zig_args, "strip", self.strip);
1706+
try addFlag(&zig_args, "formatted-panics", self.formatted_panics);
17051707
try addFlag(&zig_args, "unwind-tables", self.unwind_tables);
17061708

17071709
if (self.dwarf_format) |dwarf_format| {

lib/std/child_process.zig

Lines changed: 150 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -744,9 +744,6 @@ pub const ChildProcess = struct {
744744
windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr);
745745
};
746746

747-
const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv);
748-
defer self.allocator.free(cmd_line);
749-
750747
var siStartInfo = windows.STARTUPINFOW{
751748
.cb = @sizeOf(windows.STARTUPINFOW),
752749
.hStdError = g_hChildStd_ERR_Wr,
@@ -818,7 +815,11 @@ pub const ChildProcess = struct {
818815
const app_name_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, app_basename_utf8);
819816
defer self.allocator.free(app_name_w);
820817

821-
const cmd_line_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, cmd_line);
818+
const cmd_line_w = argvToCommandLineWindows(self.allocator, self.argv) catch |err| switch (err) {
819+
// argv[0] contains unsupported characters that will never resolve to a valid exe.
820+
error.InvalidArg0 => return error.FileNotFound,
821+
else => |e| return e,
822+
};
822823
defer self.allocator.free(cmd_line_w);
823824

824825
run: {
@@ -1236,39 +1237,159 @@ test "windowsCreateProcessSupportsExtension" {
12361237
try std.testing.expect(windowsCreateProcessSupportsExtension(&[_]u16{ '.', 'e', 'X', 'e', 'c' }) == null);
12371238
}
12381239

1239-
/// Caller must dealloc.
1240-
fn windowsCreateCommandLine(allocator: mem.Allocator, argv: []const []const u8) ![:0]u8 {
1240+
pub const ArgvToCommandLineError = error{ OutOfMemory, InvalidUtf8, InvalidArg0 };
1241+
1242+
/// Serializes `argv` to a Windows command-line string suitable for passing to a child process and
1243+
/// parsing by the `CommandLineToArgvW` algorithm. The caller owns the returned slice.
1244+
pub fn argvToCommandLineWindows(
1245+
allocator: mem.Allocator,
1246+
argv: []const []const u8,
1247+
) ArgvToCommandLineError![:0]u16 {
12411248
var buf = std.ArrayList(u8).init(allocator);
12421249
defer buf.deinit();
12431250

1244-
for (argv, 0..) |arg, arg_i| {
1245-
if (arg_i != 0) try buf.append(' ');
1246-
if (mem.indexOfAny(u8, arg, " \t\n\"") == null) {
1247-
try buf.appendSlice(arg);
1248-
continue;
1251+
if (argv.len != 0) {
1252+
const arg0 = argv[0];
1253+
1254+
// The first argument must be quoted if it contains spaces or ASCII control characters
1255+
// (excluding DEL). It also follows special quoting rules where backslashes have no special
1256+
// interpretation, which makes it impossible to pass certain first arguments containing
1257+
// double quotes to a child process without characters from the first argument leaking into
1258+
// subsequent ones (which could have security implications).
1259+
//
1260+
// Empty arguments technically don't need quotes, but we quote them anyway for maximum
1261+
// compatibility with different implementations of the 'CommandLineToArgvW' algorithm.
1262+
//
1263+
// Double quotes are illegal in paths on Windows, so for the sake of simplicity we reject
1264+
// all first arguments containing double quotes, even ones that we could theoretically
1265+
// serialize in unquoted form.
1266+
var needs_quotes = arg0.len == 0;
1267+
for (arg0) |c| {
1268+
if (c <= ' ') {
1269+
needs_quotes = true;
1270+
} else if (c == '"') {
1271+
return error.InvalidArg0;
1272+
}
12491273
}
1250-
try buf.append('"');
1251-
var backslash_count: usize = 0;
1252-
for (arg) |byte| {
1253-
switch (byte) {
1254-
'\\' => backslash_count += 1,
1255-
'"' => {
1256-
try buf.appendNTimes('\\', backslash_count * 2 + 1);
1257-
try buf.append('"');
1258-
backslash_count = 0;
1259-
},
1260-
else => {
1261-
try buf.appendNTimes('\\', backslash_count);
1262-
try buf.append(byte);
1263-
backslash_count = 0;
1264-
},
1274+
if (needs_quotes) {
1275+
try buf.append('"');
1276+
try buf.appendSlice(arg0);
1277+
try buf.append('"');
1278+
} else {
1279+
try buf.appendSlice(arg0);
1280+
}
1281+
1282+
for (argv[1..]) |arg| {
1283+
try buf.append(' ');
1284+
1285+
// Subsequent arguments must be quoted if they contain spaces, tabs or double quotes,
1286+
// or if they are empty. For simplicity and for maximum compatibility with different
1287+
// implementations of the 'CommandLineToArgvW' algorithm, we also quote all ASCII
1288+
// control characters (again, excluding DEL).
1289+
needs_quotes = for (arg) |c| {
1290+
if (c <= ' ' or c == '"') {
1291+
break true;
1292+
}
1293+
} else arg.len == 0;
1294+
if (!needs_quotes) {
1295+
try buf.appendSlice(arg);
1296+
continue;
1297+
}
1298+
1299+
try buf.append('"');
1300+
var backslash_count: usize = 0;
1301+
for (arg) |byte| {
1302+
switch (byte) {
1303+
'\\' => {
1304+
backslash_count += 1;
1305+
},
1306+
'"' => {
1307+
try buf.appendNTimes('\\', backslash_count * 2 + 1);
1308+
try buf.append('"');
1309+
backslash_count = 0;
1310+
},
1311+
else => {
1312+
try buf.appendNTimes('\\', backslash_count);
1313+
try buf.append(byte);
1314+
backslash_count = 0;
1315+
},
1316+
}
12651317
}
1318+
try buf.appendNTimes('\\', backslash_count * 2);
1319+
try buf.append('"');
12661320
}
1267-
try buf.appendNTimes('\\', backslash_count * 2);
1268-
try buf.append('"');
12691321
}
12701322

1271-
return buf.toOwnedSliceSentinel(0);
1323+
return try unicode.utf8ToUtf16LeWithNull(allocator, buf.items);
1324+
}
1325+
1326+
test "argvToCommandLineWindows" {
1327+
const t = testArgvToCommandLineWindows;
1328+
1329+
try t(&.{
1330+
\\C:\Program Files\zig\zig.exe
1331+
,
1332+
\\run
1333+
,
1334+
\\.\src\main.zig
1335+
,
1336+
\\-target
1337+
,
1338+
\\x86_64-windows-gnu
1339+
,
1340+
\\-O
1341+
,
1342+
\\ReleaseSafe
1343+
,
1344+
\\--
1345+
,
1346+
\\--emoji=🗿
1347+
,
1348+
\\--eval=new Regex("Dwayne \"The Rock\" Johnson")
1349+
,
1350+
},
1351+
\\"C:\Program Files\zig\zig.exe" run .\src\main.zig -target x86_64-windows-gnu -O ReleaseSafe -- --emoji=🗿 "--eval=new Regex(\"Dwayne \\\"The Rock\\\" Johnson\")"
1352+
);
1353+
1354+
try t(&.{}, "");
1355+
try t(&.{""}, "\"\"");
1356+
try t(&.{" "}, "\" \"");
1357+
try t(&.{"\t"}, "\"\t\"");
1358+
try t(&.{"\x07"}, "\"\x07\"");
1359+
try t(&.{"🦎"}, "🦎");
1360+
1361+
try t(
1362+
&.{ "zig", "aa aa", "bb\tbb", "cc\ncc", "dd\r\ndd", "ee\x7Fee" },
1363+
"zig \"aa aa\" \"bb\tbb\" \"cc\ncc\" \"dd\r\ndd\" ee\x7Fee",
1364+
);
1365+
1366+
try t(
1367+
&.{ "\\\\foo bar\\foo bar\\", "\\\\zig zag\\zig zag\\" },
1368+
"\"\\\\foo bar\\foo bar\\\" \"\\\\zig zag\\zig zag\\\\\"",
1369+
);
1370+
1371+
try std.testing.expectError(
1372+
error.InvalidArg0,
1373+
argvToCommandLineWindows(std.testing.allocator, &.{"\"quotes\"quotes\""}),
1374+
);
1375+
try std.testing.expectError(
1376+
error.InvalidArg0,
1377+
argvToCommandLineWindows(std.testing.allocator, &.{"quotes\"quotes"}),
1378+
);
1379+
try std.testing.expectError(
1380+
error.InvalidArg0,
1381+
argvToCommandLineWindows(std.testing.allocator, &.{"q u o t e s \" q u o t e s"}),
1382+
);
1383+
}
1384+
1385+
fn testArgvToCommandLineWindows(argv: []const []const u8, expected_cmd_line: []const u8) !void {
1386+
const cmd_line_w = try argvToCommandLineWindows(std.testing.allocator, argv);
1387+
defer std.testing.allocator.free(cmd_line_w);
1388+
1389+
const cmd_line = try unicode.utf16leToUtf8Alloc(std.testing.allocator, cmd_line_w);
1390+
defer std.testing.allocator.free(cmd_line);
1391+
1392+
try std.testing.expectEqualStrings(expected_cmd_line, cmd_line);
12721393
}
12731394

12741395
fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) void {

lib/std/crypto/kyber_d00.zig

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,8 +1020,15 @@ const Poly = struct {
10201020
// = ⌊(2ᵈ/q)x+½⌋ mod⁺ 2ᵈ
10211021
// = ⌊((x << d) + q/2) / q⌋ mod⁺ 2ᵈ
10221022
// = DIV((x << d) + q/2, q) & ((1<<d) - 1)
1023-
const t = @as(u32, @intCast(p.cs[in_off + i])) << d;
1024-
in[i] = @as(u16, @intCast(@divFloor(t + q_over_2, Q) & two_d_min_1));
1023+
const t = @as(u24, @intCast(p.cs[in_off + i])) << d;
1024+
// Division by invariant multiplication, equivalent to DIV(t + q/2, q).
1025+
// A division may not be a constant-time operation, even with a constant denominator.
1026+
// Here, side channels would leak information about the shared secret, see https://kyberslash.cr.yp.to
1027+
// Multiplication, on the other hand, is a constant-time operation on the CPUs we currently support.
1028+
comptime assert(d <= 11);
1029+
comptime assert(((20642679 * @as(u64, Q)) >> 36) == 1);
1030+
const u: u32 = @intCast((@as(u64, t + q_over_2) * 20642679) >> 36);
1031+
in[i] = @intCast(u & two_d_min_1);
10251032
}
10261033

10271034
// Now we pack the d-bit integers from `in' into out as bytes.

0 commit comments

Comments
 (0)