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 {...@@ -339,6 +339,7 @@ pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
339/// Similar to `SemanticVersion.parse`, but with following changes:339/// Similar to `SemanticVersion.parse`, but with following changes:
340/// * Leading zeroes are allowed.340/// * Leading zeroes are allowed.
341/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0.341/// * 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.
342pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {343pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {
343 const parseVersionComponentFn = (struct {344 const parseVersionComponentFn = (struct {
344 fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {345 fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {
...@@ -348,11 +349,14 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV...@@ -348,11 +349,14 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
348 };349 };
349 }350 }
350 }).parseVersionComponentInner;351 }).parseVersionComponentInner;
352
351 var version_components = mem.splitScalar(u8, ver, '.');353 var version_components = mem.splitScalar(u8, ver, '.');
354
352 const major = version_components.first();355 const major = version_components.first();
353 const minor = version_components.next() orelse return error.InvalidVersion;356 const minor = version_components.next() orelse return error.InvalidVersion;
354 const patch = version_components.next() orelse "0";357 const patch = version_components.next() orelse "0";
355 if (version_components.next() != null) return error.InvalidVersion;358 if (version_components.next() != null) return error.InvalidVersion;
359
356 return .{360 return .{
357 .major = try parseVersionComponentFn(major),361 .major = try parseVersionComponentFn(major),
358 .minor = try parseVersionComponentFn(minor),362 .minor = try parseVersionComponentFn(minor),
...@@ -361,10 +365,12 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV...@@ -361,10 +365,12 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
361}365}
362366
363test parseVersion {367test parseVersion {
364 try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
365 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));368 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));
366 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3"));369 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"));
367 try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));372 try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));
373 try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3-dev"));
368}374}
369375
370pub fn isNativeCpu(self: Query) bool {376pub fn isNativeCpu(self: Query) bool {
lib/std/zig/system.zig+11-23
...@@ -215,25 +215,17 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {...@@ -215,25 +215,17 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
215 var os = query_os_tag.defaultVersionRange(query_cpu_arch, query_abi);215 var os = query_os_tag.defaultVersionRange(query_cpu_arch, query_abi);
216 if (query.os_tag == null) {216 if (query.os_tag == null) {
217 switch (builtin.target.os.tag) {217 switch (builtin.target.os.tag) {
218 .linux => {218 .linux, .illumos => {
219 const uts = posix.uname();219 const uts = posix.uname();
220 const release = mem.sliceTo(&uts.release, 0);220 const release = mem.sliceTo(&uts.release, 0);
221 // The release field sometimes has a weird format,221 // The release field sometimes has a weird format,
222 // `Version.parse` will attempt to find some meaningful interpretation.222 // `Version.parse` will attempt to find some meaningful interpretation.
223 if (std.SemanticVersion.parse(release)) |ver| {223 if (std.SemanticVersion.parse(release)) |ver| {
224 os.version_range.linux.range.min = ver;224 var stripped = ver;
225 os.version_range.linux.range.max = ver;225 stripped.pre = null;
226 } else |err| switch (err) {226 stripped.build = null;
227 error.Overflow => {},227 os.version_range.linux.range.min = stripped;
228 error.InvalidVersion => {},228 os.version_range.linux.range.max = stripped;
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;
237 } else |err| switch (err) {229 } else |err| switch (err) {
238 error.Overflow => {},230 error.Overflow => {},
239 error.InvalidVersion => {},231 error.InvalidVersion => {},
...@@ -307,10 +299,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {...@@ -307,10 +299,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
307 posix.CTL.KERN,299 posix.CTL.KERN,
308 posix.KERN.OSRELEASE,300 posix.KERN.OSRELEASE,
309 };301 };
310 var buf: [64]u8 = undefined;302 var buf: [64:0]u8 = undefined;
311 // consider that sysctl result includes null-termination303 // consider that sysctl result includes null-termination
312 // reserve 1 byte to ensure we never overflow when appending ".0"304 var len: usize = buf.len + 1;
313 var len: usize = buf.len - 1;
314305
315 posix.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {306 posix.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {
316 error.NameTooLong => unreachable, // constant, known good value307 error.NameTooLong => unreachable, // constant, known good value
...@@ -320,12 +311,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {...@@ -320,12 +311,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
320 error.Unexpected => return error.OSVersionDetectionFail,311 error.Unexpected => return error.OSVersionDetectionFail,
321 };312 };
322313
323 // append ".0" to satisfy semver314 if (Target.Query.parseVersion(buf[0..len :0])) |ver| {
324 buf[len - 1] = '.';315 assert(ver.build == null);
325 buf[len] = '0';316 assert(ver.pre == null);
326 len += 1;
327
328 if (std.SemanticVersion.parse(buf[0..len])) |ver| {
329 os.version_range.semver.min = ver;317 os.version_range.semver.min = ver;
330 os.version_range.semver.max = ver;318 os.version_range.semver.max = ver;
331 } else |_| {319 } else |_| {
lib/std/zig/system/darwin/macos.zig+2
...@@ -58,6 +58,8 @@ pub fn detect(target_os: *Target.Os) !void {...@@ -58,6 +58,8 @@ pub fn detect(target_os: *Target.Os) !void {
58 if (parseSystemVersion(bytes)) |ver| {58 if (parseSystemVersion(bytes)) |ver| {
59 // never return non-canonical `10.(16+)`59 // never return non-canonical `10.(16+)`
60 if (!(ver.major == 10 and ver.minor >= 16)) {60 if (!(ver.major == 10 and ver.minor >= 16)) {
61 assert(ver.pre == null);
62 assert(ver.build == null);
61 target_os.version_range.semver.min = ver;63 target_os.version_range.semver.min = ver;
62 target_os.version_range.semver.max = ver;64 target_os.version_range.semver.max = ver;
63 return;65 return;