Skip to content

Commit 5932d67

Browse files
jamesadevineCopilot
andcommitted
fix(safeoutputs): support glob wildcards anywhere in allowed-tags patterns
tag_matches_pattern only handled a trailing '*' (prefix match). Patterns like 'copilot:repo=msazuresphere/4x4/*@main' silently fell through to exact-match comparison, rejecting valid tags such as 'copilot:repo=msazuresphere/4x4/VsCodeExtension@main'. Switch to glob_match::glob_match (already a dependency) so '*' works in any position. Also consolidate the inline matching in add_build_tag.rs to use the shared tag_matches_pattern helper, gaining case-insensitive matching it was previously missing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 018856e commit 5932d67

2 files changed

Lines changed: 36 additions & 13 deletions

File tree

src/safeoutputs/add_build_tag.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,10 @@ impl Executor for AddBuildTagResult {
161161

162162
// 4. Validate against allowed tags (if non-empty)
163163
if !config.allowed_tags.is_empty() {
164-
let allowed = config.allowed_tags.iter().any(|pattern| {
165-
if let Some(prefix) = pattern.strip_suffix('*') {
166-
final_tag.starts_with(prefix)
167-
} else {
168-
*pattern == final_tag
169-
}
170-
});
164+
let allowed = config
165+
.allowed_tags
166+
.iter()
167+
.any(|pattern| super::tag_matches_pattern(&final_tag, pattern));
171168
if !allowed {
172169
return Ok(ExecutionResult::failure(format!(
173170
"Tag '{}' is not in the allowed tags list",

src/safeoutputs/mod.rs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,13 @@ pub(crate) fn resolve_repo_name(
218218
///
219219
/// Both comparisons are **case-insensitive** so that an operator who writes
220220
/// `allowed-tags: ["Agent-*"]` correctly matches an agent-provided tag `"agent-created"`.
221+
///
222+
/// Supports `*` wildcards anywhere in the pattern (e.g. `copilot:repo=org/project/*@main`).
221223
pub(crate) fn tag_matches_pattern(tag: &str, pattern: &str) -> bool {
222-
if let Some(prefix) = pattern.strip_suffix('*') {
223-
tag.to_ascii_lowercase()
224-
.starts_with(&prefix.to_ascii_lowercase())
225-
} else {
226-
pattern.eq_ignore_ascii_case(tag)
227-
}
224+
glob_match::glob_match(
225+
&pattern.to_ascii_lowercase(),
226+
&tag.to_ascii_lowercase(),
227+
)
228228
}
229229

230230
/// Validate a string against `git check-ref-format` rules.
@@ -515,4 +515,30 @@ mod tests {
515515
assert!(tag_matches_pattern("anything", "*"));
516516
assert!(tag_matches_pattern("", "*"));
517517
}
518+
519+
#[test]
520+
fn test_tag_matches_pattern_middle_wildcard() {
521+
// Glob wildcard in the middle of the pattern
522+
assert!(tag_matches_pattern(
523+
"copilot:repo=msazuresphere/4x4/VsCodeExtension@main",
524+
"copilot:repo=msazuresphere/4x4/*@main"
525+
));
526+
assert!(tag_matches_pattern(
527+
"copilot:repo=msazuresphere/4x4/DevTools@main",
528+
"copilot:repo=msazuresphere/4x4/*@main"
529+
));
530+
// Wrong suffix should not match
531+
assert!(!tag_matches_pattern(
532+
"copilot:repo=msazuresphere/4x4/DevTools@dev",
533+
"copilot:repo=msazuresphere/4x4/*@main"
534+
));
535+
}
536+
537+
#[test]
538+
fn test_tag_matches_pattern_middle_wildcard_case_insensitive() {
539+
assert!(tag_matches_pattern(
540+
"Copilot:Repo=MSAzureSphere/4x4/Tools@Main",
541+
"copilot:repo=msazuresphere/4x4/*@main"
542+
));
543+
}
518544
}

0 commit comments

Comments
 (0)