diff options
author | 2023-08-22 20:19:04 -0700 | |
---|---|---|
committer | 2023-08-22 20:19:04 -0700 | |
commit | 6dd318ae611d2434397821278238e964adfe36a8 (patch) | |
tree | ef6fb685a7c3a05f96be33de874b3833ea558556 | |
parent | d86084dd8e69d41ae36303024e330e257df534b7 (diff) | |
download | bun-6dd318ae611d2434397821278238e964adfe36a8.tar.gz bun-6dd318ae611d2434397821278238e964adfe36a8.tar.zst bun-6dd318ae611d2434397821278238e964adfe36a8.zip |
fix installing `grunt-contrib-yuidoc`dave/install-tag-without-dash
-rw-r--r-- | src/install/npm.zig | 2 | ||||
-rw-r--r-- | src/install/semver.zig | 31 |
2 files changed, 32 insertions, 1 deletions
diff --git a/src/install/npm.zig b/src/install/npm.zig index 0a25fe636..b6c8daa01 100644 --- a/src/install/npm.zig +++ b/src/install/npm.zig @@ -847,7 +847,7 @@ pub const PackageManifest = struct { for (versions) |prop| { const version_name = prop.key.?.asString(allocator) orelse continue; - if (strings.indexOfChar(version_name, '-') != null) { + if (Semver.Version.stringHasPrereleaseTag(version_name)) { pre_versions_len += 1; extern_string_count += 1; } else { diff --git a/src/install/semver.zig b/src/install/semver.zig index 1ec76b370..f7d7df71c 100644 --- a/src/install/semver.zig +++ b/src/install/semver.zig @@ -1151,6 +1151,37 @@ pub const Version = extern struct { return std.fmt.parseInt(u32, bytes[0..byte_i], 10) catch 0; } + + /// Without doing a full semver parse, will this string parse to contain a pre-release tag? + /// Does not check for a valid semver, return value is only valid if the input is a valid semver. + /// + /// This is used by PackageManifest.parse() to classify strings, and determines how + /// much memory to allocate for package version entries in two lists. + /// + /// If all npm packages were strict semvers, this test would only do "contains('-')", but some + /// packages expect a version like "1.0.0rc7" which wouldn't work here. A mismatch between this + /// pre-prediction function and the actual semver parser will end up causing a segfault due to + /// incorrect memory allocation later on. + /// + /// Strings that contain a pre-release tag: + /// "1.0.0-hello" (there is a dash) + /// "1.0.0-0" (there is a dash) + /// "3.7.5rc" (there is letters A-Z or a-z) + /// Strings that do not contain a pre-release tag: + /// "1.0.0" (no dash or letters) + /// "1.0.0+hello" (a plus is a post-release) + pub fn stringHasPrereleaseTag(input: []const u8) bool { + var i: usize = 0; + while (i < input.len) { + switch (input[i]) { + '-', 'A'...'Z', 'a'...'z' => return true, + '+' => return false, + else => {}, + } + i += 1; + } + return false; + } }; pub const Range = struct { |