Skip to content

Commit a8e01c4

Browse files
committed
preparing for v1.100.0
1 parent a148a15 commit a8e01c4

3 files changed

Lines changed: 57 additions & 17 deletions

File tree

src/scanner/enumerate.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,12 @@ fn try_extract_git_blob_archive(
718718
if entries.is_empty() { Ok(None) } else { Ok(Some(entries)) }
719719
}
720720

721+
fn archive_entry_suffix<'a>(entry_logical: &'a str, archive_path: &str) -> Option<&'a str> {
722+
entry_logical.strip_prefix(archive_path).filter(|suffix| suffix.starts_with('!')).or_else(
723+
|| entry_logical.split_once('!').map(|(archive, _)| &entry_logical[archive.len()..]),
724+
)
725+
}
726+
721727
// A marker so the struct itself carries the lifetime.
722728
struct GitRepoResultIter<'a> {
723729
inner: GitRepoResult,
@@ -798,12 +804,21 @@ impl<'a> rayon::iter::ParallelIterator for GitRepoResultIter<'a> {
798804
Ok(Some(entries)) => {
799805
let mut out = Vec::with_capacity(entries.len());
800806
for (entry_logical, entry_bytes) in entries {
807+
let entry_suffix =
808+
archive_entry_suffix(&entry_logical, &archive_path);
801809
let origin =
802810
OriginSet::try_from_iter(md.first_seen.iter().map(|e| {
811+
let repo_relative_path =
812+
String::from_utf8_lossy(&e.path).to_string();
813+
let per_appearance_logical = entry_suffix
814+
.map(|suffix| {
815+
format!("{repo_relative_path}{suffix}")
816+
})
817+
.unwrap_or_else(|| entry_logical.clone());
803818
Origin::from_git_repo_with_first_commit(
804819
Arc::clone(&repo_path),
805820
Arc::clone(&e.commit_metadata),
806-
entry_logical.clone(),
821+
per_appearance_logical,
807822
)
808823
}))
809824
.unwrap_or_else(
@@ -1560,6 +1575,18 @@ mod tests {
15601575
Ok(())
15611576
}
15621577

1578+
#[test]
1579+
fn archive_entry_suffix_preserves_entry_component() {
1580+
assert_eq!(
1581+
super::archive_entry_suffix("dir/archive.zip!nested/secret.txt", "dir/archive.zip"),
1582+
Some("!nested/secret.txt")
1583+
);
1584+
assert_eq!(
1585+
super::archive_entry_suffix("archive.zip!nested/secret.txt", "other/archive.zip"),
1586+
Some("!nested/secret.txt")
1587+
);
1588+
}
1589+
15631590
#[test]
15641591
fn git_blob_archive_extraction_preserves_repo_relative_paths() -> Result<()> {
15651592
let mut cursor = std::io::Cursor::new(Vec::new());

src/scanner/validation.rs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,8 +1001,9 @@ fn maybe_record_access_map(om: &OwnedBlobMatch, collector: Option<&AccessMapColl
10011001
.map(|(_, value, ..)| value.clone())
10021002
.unwrap_or_default();
10031003

1004-
let mut akid = utils::find_closest_variable(&captures, &secret, "TOKEN", "AKID")
1005-
.unwrap_or_default();
1004+
let mut akid =
1005+
utils::find_closest_variable(&captures, secret.as_str(), "TOKEN", "AKID")
1006+
.unwrap_or_default();
10061007

10071008
if akid.is_empty() {
10081009
akid = extract_akid_from_body(&om.validation_response_body).unwrap_or_default();
@@ -1026,7 +1027,7 @@ fn maybe_record_access_map(om: &OwnedBlobMatch, collector: Option<&AccessMapColl
10261027
.map(|(_, value, ..)| value.clone())
10271028
.unwrap_or_default();
10281029
let storage_account =
1029-
utils::find_closest_variable(&captures, &storage_key, "TOKEN", "AZURENAME")
1030+
utils::find_closest_variable(&captures, storage_key.as_str(), "TOKEN", "AZURENAME")
10301031
.unwrap_or_default();
10311032

10321033
let mut storage_account = storage_account;
@@ -1081,9 +1082,13 @@ fn maybe_record_access_map(om: &OwnedBlobMatch, collector: Option<&AccessMapColl
10811082
.find(|(name, ..)| name == "TOKEN")
10821083
.map(|(_, value, ..)| value.clone())
10831084
.unwrap_or_default();
1084-
let mut organization =
1085-
utils::find_closest_variable(&captures, &token, "TOKEN", "AZURE_DEVOPS_ORG")
1086-
.unwrap_or_default();
1085+
let mut organization = utils::find_closest_variable(
1086+
&captures,
1087+
token.as_str(),
1088+
"TOKEN",
1089+
"AZURE_DEVOPS_ORG",
1090+
)
1091+
.unwrap_or_default();
10871092
if organization.is_empty() {
10881093
organization = extract_azure_devops_org_from_body(&om.validation_response_body)
10891094
.unwrap_or_default();
@@ -1100,7 +1105,7 @@ fn maybe_record_access_map(om: &OwnedBlobMatch, collector: Option<&AccessMapColl
11001105
.map(|(_, value, ..)| value.clone())
11011106
.unwrap_or_default();
11021107
let access_key =
1103-
utils::find_closest_variable(&captures, &secret_key, "TOKEN", "AKID")
1108+
utils::find_closest_variable(&captures, secret_key.as_str(), "TOKEN", "AKID")
11041109
.or_else(|| om.dependent_captures.get("AKID").cloned())
11051110
.unwrap_or_default();
11061111

@@ -1114,14 +1119,22 @@ fn maybe_record_access_map(om: &OwnedBlobMatch, collector: Option<&AccessMapColl
11141119
.find(|(name, ..)| name == "TOKEN")
11151120
.map(|(_, value, ..)| value.clone())
11161121
.unwrap_or_default();
1117-
let access_key =
1118-
utils::find_closest_variable(&captures, &secret_key, "TOKEN", "STS_AKID")
1119-
.or_else(|| om.dependent_captures.get("STS_AKID").cloned())
1120-
.unwrap_or_default();
1121-
let session_token =
1122-
utils::find_closest_variable(&captures, &secret_key, "TOKEN", "SECURITY_TOKEN")
1123-
.or_else(|| om.dependent_captures.get("SECURITY_TOKEN").cloned())
1124-
.unwrap_or_default();
1122+
let access_key = utils::find_closest_variable(
1123+
&captures,
1124+
secret_key.as_str(),
1125+
"TOKEN",
1126+
"STS_AKID",
1127+
)
1128+
.or_else(|| om.dependent_captures.get("STS_AKID").cloned())
1129+
.unwrap_or_default();
1130+
let session_token = utils::find_closest_variable(
1131+
&captures,
1132+
secret_key.as_str(),
1133+
"TOKEN",
1134+
"SECURITY_TOKEN",
1135+
)
1136+
.or_else(|| om.dependent_captures.get("SECURITY_TOKEN").cloned())
1137+
.unwrap_or_default();
11251138

11261139
if !access_key.is_empty() && !secret_key.is_empty() && !session_token.is_empty() {
11271140
collector.record_alibaba(

src/validation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1195,7 +1195,7 @@ async fn validate_azure_storage(
11951195
.map(|(_, v, ..)| v.clone())
11961196
.unwrap_or_default();
11971197
let storage_account =
1198-
utils::find_closest_variable(captured_values, &storage_key, "TOKEN", "AZURENAME")
1198+
utils::find_closest_variable(captured_values, storage_key.as_str(), "TOKEN", "AZURENAME")
11991199
.unwrap_or_default();
12001200

12011201
if storage_account.is_empty() || storage_key.is_empty() {

0 commit comments

Comments
 (0)