ReviewOS

also looking at this

craft-native/craft

feat(maps): add key-free native Android maps and shared map controls

#363
Merged chris wants to merge codex/wildloop-native-map-providers into main
28 files +1857 -481

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

packages/zig/build.zigmodified+9-0
Changes to packages/zig/build.zig
@@ -1960,6 +1960,15 @@ pub fn build(b: *std.Build) void {
19601960 }
19611961
19621962 const test_step = b.step("test", "Run all unit tests");
1963 const io_backend_tests = b.addTest(.{
1964 .root_module = b.createModule(.{
1965 .root_source_file = b.path("src/io_backend.zig"),
1966 .target = target,
1967 .optimize = optimize,
1968 .link_libc = true,
1969 }),
1970 });
1971 test_step.dependOn(&b.addRunArtifact(io_backend_tests).step);
19631972 test_step.dependOn(&run_lib_unit_tests.step);
19641973 if (js_test_run) |run| test_step.dependOn(&run.step);
19651974 test_step.dependOn(&run_api_tests.step);
packages/zig/src/global_state.zigmodified+1-1
Changes to packages/zig/src/global_state.zig
@@ -200,7 +200,7 @@ pub const GlobalState = struct {
200200
201201 // Lazy init for test mode or when not explicitly initialized
202202 self.default_threaded = std.Io.Threaded.init(std.heap.c_allocator, .{ .environ = .empty });
203 self.io = self.default_threaded.?.io();
203 self.io = .threadedIo(&self.default_threaded.?);
204204 return self.io.?;
205205 }
206206
packages/zig/src/io_backend.zigadded+46-0
Changes to packages/zig/src/io_backend.zig
@@ -0,0 +1,46 @@
1//! Craft's platform policy for the standard threaded I/O backend.
2//! Sandboxed Apple apps cannot replace their running process. Apply that
3//! restriction when constructing the vtable, before desktop process code is
4//! instantiated; file, network and concurrency operations remain unchanged.
5const std = ;
6const builtin = ;
7
8pub fn threadedIo(threaded: *std.Io.Threaded) std.Io {
9 return switch (builtin.os.tag) {
10 .ios, .tvos, .visionos, .watchos => sandboxedIo(threaded),
11 else => threaded.io(),
12 };
13}
14
15fn sandboxedIo(threaded: *std.Io.Threaded) std.Io {
16 const vtable = comptime blk: {
17 var table = std.Io.Threaded.io(undefined).vtable.*;
18 table.processReplace = processReplaceUnsupported;
19 break :blk table;
20 };
21 return .{ .userdata = threaded, .vtable = &vtable };
22}
23
24fn processReplaceUnsupported(_: ?*anyopaque, _: std.process.ReplaceOptions) std.process.ReplaceError {
25 return error.OperationUnsupported;
26}
27
28test "sandboxed Io refuses process replacement without accessing backend state" {
29 try std.testing.expectEqual(error.OperationUnsupported, processReplaceUnsupported(null, .{ .argv = &.{"/never-executed"} }));
30 var threaded: std.Io.Threaded = undefined;
31 const io = sandboxedIo(&threaded);
32 try std.testing.expectEqual(error.OperationUnsupported, std.process.replace(io, .{ .argv = &.{"/never-executed"} }));
33 try std.testing.expectEqual(@as(?*anyopaque, &threaded), io.userdata);
34}
35
36test "sandboxed Io retains standard file network and concurrency operations" {
37 var threaded: std.Io.Threaded = undefined;
38 const standard = threaded.io();
39 const sandboxed = sandboxedIo(&threaded);
40 inline for (.{ "fileReadPositional", "fileWritePositional", "dirOpenDir", "netConnectIp", "async", "sleep" }) |name| {
41 try std.testing.expectEqual(@field(standard.vtable, name), @field(sandboxed.vtable, name));
42 }
43 if (comptime builtin.os.tag != .ios and builtin.os.tag != .tvos and builtin.os.tag != .visionos and builtin.os.tag != .watchos) {
44 try std.testing.expectEqual(standard.vtable, threadedIo(&threaded).vtable);
45 }
46}