Skip to content
This repository was archived by the owner on Oct 2, 2025. It is now read-only.

Commit 00d2b5d

Browse files
committed
handle encoded tags, allow / and trim quotes in tags
1 parent ec8cb71 commit 00d2b5d

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

src/platform.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use url::Url;
1212
use crate::{
1313
downloader::{DownloadOptions, DownloadState, Downloader},
1414
error::{DownloadError, PlatformError},
15-
utils::{matches_pattern, should_fallback},
15+
utils::{decode_uri, matches_pattern, should_fallback},
1616
};
1717

1818
pub enum ApiType {
@@ -29,11 +29,13 @@ pub enum PlatformUrl {
2929
}
3030

3131
static GITHUB_RELEASE_RE: LazyLock<Regex> = LazyLock::new(|| {
32-
Regex::new(r"^(?i)(?:https?://)?(?:github(?:\.com)?[:/])([^/@]+/[^/@]+)(?:@([^/\s]*)?)?$")
33-
.unwrap()
32+
Regex::new(
33+
r"^(?i)(?:https?://)?(?:github(?:\.com)?[:/])([^/@]+/[^/@]+)(?:@([^/\s]+(?:/[^/\s]*)*)?)?$",
34+
)
35+
.unwrap()
3436
});
3537
static GITLAB_RELEASE_RE: LazyLock<Regex> = LazyLock::new(|| {
36-
Regex::new(r"^(?i)(?:https?://)?(?:gitlab(?:\.com)?[:/])((?:\d+)|(?:[^/@]+(?:/[^/@]+)*))(?:@([^/\s]*)?)?$")
38+
Regex::new(r"^(?i)(?:https?://)?(?:gitlab(?:\.com)?[:/])((?:\d+)|(?:[^/@]+(?:/[^/@]+)*))(?:@([^/\s]+(?:/[^/\s]*)*)?)?$")
3739
.unwrap()
3840
});
3941

@@ -48,8 +50,9 @@ impl PlatformUrl {
4850
let project = caps.get(1).unwrap().as_str();
4951
let tag = caps
5052
.get(2)
51-
.map(|tag| tag.as_str().trim())
52-
.filter(|&tag| !tag.is_empty());
53+
.map(|tag| tag.as_str().trim_matches(&['\'', '"', ' '][..]))
54+
.filter(|&tag| !tag.is_empty())
55+
.map(decode_uri);
5356
if let Some(tag) = tag {
5457
return Ok(PlatformUrl::Github(format!("{}@{}", project, tag)));
5558
} else {
@@ -67,8 +70,9 @@ impl PlatformUrl {
6770
}
6871
let tag = caps
6972
.get(2)
70-
.map(|tag| tag.as_str().trim())
71-
.filter(|&tag| !tag.is_empty());
73+
.map(|tag| tag.as_str().trim_matches(&['\'', '"', ' '][..]))
74+
.filter(|&tag| !tag.is_empty())
75+
.map(decode_uri);
7276
if let Some(tag) = tag {
7377
return Ok(PlatformUrl::Gitlab(format!("{}@{}", project, tag)));
7478
} else {

src/utils.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,23 @@ pub fn matches_pattern(
9191
})
9292
})
9393
}
94+
95+
pub fn decode_uri(s: impl AsRef<str>) -> String {
96+
let re = Regex::new(r"(%[A-Fa-f0-9]{2})+").unwrap();
97+
98+
re.replace_all(s.as_ref(), |caps: &regex::Captures| {
99+
let seq = caps.get(0).map_or("", |m| m.as_str());
100+
let mut r = Vec::<u8>::new();
101+
let inp: Vec<u8> = seq.bytes().collect();
102+
let mut i: usize = 0;
103+
while i != inp.len() {
104+
r.push(
105+
u8::from_str_radix(&String::from_utf8_lossy(&[inp[i + 1], inp[i + 2]]), 16)
106+
.unwrap_or(0),
107+
);
108+
i += 3;
109+
}
110+
String::from_utf8_lossy(&r).into_owned()
111+
})
112+
.into_owned()
113+
}

0 commit comments

Comments
 (0)