authorgravatar for 69403556+SeanTUT@users.noreply.github.comSean <69403556+SeanTUT@users.noreply.github.com> 2025-10-28 05:17:09-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-10-28 10:17:09+01:00
log35e1755c996eb1cff77ff262d93302e5d6f16f9a
tree8e661dbdd59e4b4b0596dd5fa88926ba96afdc19
parentdba1bf935390ddb0184a4dc72245454de6c06fd2
signaturebadge-check Signed by PGP key B5690EEEBB952194

Fix stale reference bug in `std.zig.system.resolveTargetQuery` (#25713)

Co-authored-by: Alex Rønne Petersen <alex@alexrp.com>

3 files changed, 20 insertions(+), 24 deletions(-)

lib/std/Target/Query.zig+7-1
......@@ -339,6 +339,7 @@ pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
339339/// Similar to `SemanticVersion.parse`, but with following changes:
340340/// * Leading zeroes are allowed.
341341/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0.
342/// * Prerelease and build components are disallowed.
342343pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {
343344 const parseVersionComponentFn = (struct {
344345 fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {
......@@ -348,11 +349,14 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
348349 };
349350 }
350351 }).parseVersionComponentInner;
352
351353 var version_components = mem.splitScalar(u8, ver, '.');
354
352355 const major = version_components.first();
353356 const minor = version_components.next() orelse return error.InvalidVersion;
354357 const patch = version_components.next() orelse "0";
355358 if (version_components.next() != null) return error.InvalidVersion;
359
356360 return .{
357361 .major = try parseVersionComponentFn(major),
358362 .minor = try parseVersionComponentFn(minor),
......@@ -361,10 +365,12 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
361365}
362366
363367test parseVersion {
364 try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
365368 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));
366369 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3"));
370
371 try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
367372 try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));
373 try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3-dev"));
368374}
369375
370376pub fn isNativeCpu(self: Query) bool {
lib/std/zig/system.zig+11-23
......@@ -215,25 +215,17 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
215215 var os = query_os_tag.defaultVersionRange(query_cpu_arch, query_abi);
216216 if (query.os_tag == null) {
217217 switch (builtin.target.os.tag) {
218 .linux => {
218 .linux, .illumos => {
219219 const uts = posix.uname();
220220 const release = mem.sliceTo(&uts.release, 0);
221221 // The release field sometimes has a weird format,
222222 // `Version.parse` will attempt to find some meaningful interpretation.
223223 if (std.SemanticVersion.parse(release)) |ver| {
224 os.version_range.linux.range.min = ver;
225 os.version_range.linux.range.max = ver;
226 } else |err| switch (err) {
227 error.Overflow => {},
228 error.InvalidVersion => {},
229 }
230 },
231 .illumos => {
232 const uts = posix.uname();
233 const release = mem.sliceTo(&uts.release, 0);
234 if (std.SemanticVersion.parse(release)) |ver| {
235 os.version_range.semver.min = ver;
236 os.version_range.semver.max = ver;
224 var stripped = ver;
225 stripped.pre = null;
226 stripped.build = null;
227 os.version_range.linux.range.min = stripped;
228 os.version_range.linux.range.max = stripped;
237229 } else |err| switch (err) {
238230 error.Overflow => {},
239231 error.InvalidVersion => {},
......@@ -307,10 +299,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
307299 posix.CTL.KERN,
308300 posix.KERN.OSRELEASE,
309301 };
310 var buf: [64]u8 = undefined;
302 var buf: [64:0]u8 = undefined;
311303 // consider that sysctl result includes null-termination
312 // reserve 1 byte to ensure we never overflow when appending ".0"
313 var len: usize = buf.len - 1;
304 var len: usize = buf.len + 1;
314305
315306 posix.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {
316307 error.NameTooLong => unreachable, // constant, known good value
......@@ -320,12 +311,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
320311 error.Unexpected => return error.OSVersionDetectionFail,
321312 };
322313
323 // append ".0" to satisfy semver
324 buf[len - 1] = '.';
325 buf[len] = '0';
326 len += 1;
327
328 if (std.SemanticVersion.parse(buf[0..len])) |ver| {
314 if (Target.Query.parseVersion(buf[0..len :0])) |ver| {
315 assert(ver.build == null);
316 assert(ver.pre == null);
329317 os.version_range.semver.min = ver;
330318 os.version_range.semver.max = ver;
331319 } else |_| {
lib/std/zig/system/darwin/macos.zig+2
......@@ -58,6 +58,8 @@ pub fn detect(target_os: *Target.Os) !void {
5858 if (parseSystemVersion(bytes)) |ver| {
5959 // never return non-canonical `10.(16+)`
6060 if (!(ver.major == 10 and ver.minor >= 16)) {
61 assert(ver.pre == null);
62 assert(ver.build == null);
6163 target_os.version_range.semver.min = ver;
6264 target_os.version_range.semver.max = ver;
6365 return;