mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Fix stale reference bug in std.zig.system.resolveTargetQuery (#25713)
Co-authored-by: Alex Rønne Petersen <alex@alexrp.com>
This commit is contained in:
parent
dba1bf9353
commit
35e1755c99
@ -339,6 +339,7 @@ pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
|
||||
/// Similar to `SemanticVersion.parse`, but with following changes:
|
||||
/// * Leading zeroes are allowed.
|
||||
/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0.
|
||||
/// * Prerelease and build components are disallowed.
|
||||
pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {
|
||||
const parseVersionComponentFn = (struct {
|
||||
fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {
|
||||
@ -348,11 +349,14 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
|
||||
};
|
||||
}
|
||||
}).parseVersionComponentInner;
|
||||
|
||||
var version_components = mem.splitScalar(u8, ver, '.');
|
||||
|
||||
const major = version_components.first();
|
||||
const minor = version_components.next() orelse return error.InvalidVersion;
|
||||
const patch = version_components.next() orelse "0";
|
||||
if (version_components.next() != null) return error.InvalidVersion;
|
||||
|
||||
return .{
|
||||
.major = try parseVersionComponentFn(major),
|
||||
.minor = try parseVersionComponentFn(minor),
|
||||
@ -361,10 +365,12 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
|
||||
}
|
||||
|
||||
test parseVersion {
|
||||
try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
|
||||
try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));
|
||||
try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3"));
|
||||
|
||||
try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
|
||||
try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));
|
||||
try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3-dev"));
|
||||
}
|
||||
|
||||
pub fn isNativeCpu(self: Query) bool {
|
||||
|
||||
@ -215,25 +215,17 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
|
||||
var os = query_os_tag.defaultVersionRange(query_cpu_arch, query_abi);
|
||||
if (query.os_tag == null) {
|
||||
switch (builtin.target.os.tag) {
|
||||
.linux => {
|
||||
.linux, .illumos => {
|
||||
const uts = posix.uname();
|
||||
const release = mem.sliceTo(&uts.release, 0);
|
||||
// The release field sometimes has a weird format,
|
||||
// `Version.parse` will attempt to find some meaningful interpretation.
|
||||
if (std.SemanticVersion.parse(release)) |ver| {
|
||||
os.version_range.linux.range.min = ver;
|
||||
os.version_range.linux.range.max = ver;
|
||||
} else |err| switch (err) {
|
||||
error.Overflow => {},
|
||||
error.InvalidVersion => {},
|
||||
}
|
||||
},
|
||||
.illumos => {
|
||||
const uts = posix.uname();
|
||||
const release = mem.sliceTo(&uts.release, 0);
|
||||
if (std.SemanticVersion.parse(release)) |ver| {
|
||||
os.version_range.semver.min = ver;
|
||||
os.version_range.semver.max = ver;
|
||||
var stripped = ver;
|
||||
stripped.pre = null;
|
||||
stripped.build = null;
|
||||
os.version_range.linux.range.min = stripped;
|
||||
os.version_range.linux.range.max = stripped;
|
||||
} else |err| switch (err) {
|
||||
error.Overflow => {},
|
||||
error.InvalidVersion => {},
|
||||
@ -307,10 +299,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
|
||||
posix.CTL.KERN,
|
||||
posix.KERN.OSRELEASE,
|
||||
};
|
||||
var buf: [64]u8 = undefined;
|
||||
var buf: [64:0]u8 = undefined;
|
||||
// consider that sysctl result includes null-termination
|
||||
// reserve 1 byte to ensure we never overflow when appending ".0"
|
||||
var len: usize = buf.len - 1;
|
||||
var len: usize = buf.len + 1;
|
||||
|
||||
posix.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {
|
||||
error.NameTooLong => unreachable, // constant, known good value
|
||||
@ -320,12 +311,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
|
||||
error.Unexpected => return error.OSVersionDetectionFail,
|
||||
};
|
||||
|
||||
// append ".0" to satisfy semver
|
||||
buf[len - 1] = '.';
|
||||
buf[len] = '0';
|
||||
len += 1;
|
||||
|
||||
if (std.SemanticVersion.parse(buf[0..len])) |ver| {
|
||||
if (Target.Query.parseVersion(buf[0..len :0])) |ver| {
|
||||
assert(ver.build == null);
|
||||
assert(ver.pre == null);
|
||||
os.version_range.semver.min = ver;
|
||||
os.version_range.semver.max = ver;
|
||||
} else |_| {
|
||||
|
||||
@ -58,6 +58,8 @@ pub fn detect(target_os: *Target.Os) !void {
|
||||
if (parseSystemVersion(bytes)) |ver| {
|
||||
// never return non-canonical `10.(16+)`
|
||||
if (!(ver.major == 10 and ver.minor >= 16)) {
|
||||
assert(ver.pre == null);
|
||||
assert(ver.build == null);
|
||||
target_os.version_range.semver.min = ver;
|
||||
target_os.version_range.semver.max = ver;
|
||||
return;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user