Skip to content

Commit 35e1755

Browse files
SeanTUTalexrp
andauthored
Fix stale reference bug in std.zig.system.resolveTargetQuery (#25713)
Co-authored-by: Alex Rønne Petersen <[email protected]>
1 parent dba1bf9 commit 35e1755

File tree

3 files changed

+20
-24
lines changed

3 files changed

+20
-24
lines changed

lib/std/Target/Query.zig

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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.
342343
pub 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

363367
test 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

370376
pub fn isNativeCpu(self: Query) bool {

lib/std/zig/system.zig

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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;

0 commit comments

Comments
 (0)