forked from mirrors/kingfisher
v1.80.0
This commit is contained in:
parent
a24f38fdfd
commit
2a8bb9c361
2 changed files with 81 additions and 8 deletions
|
|
@ -219,6 +219,9 @@ fn render_extractor(
|
|||
globals: &Object,
|
||||
) -> Result<ResponseExtractor> {
|
||||
let render = |template_str: &str| -> Result<String> {
|
||||
if !template_str.contains("{{") && !template_str.contains("{%") {
|
||||
return Ok(template_str.to_string());
|
||||
}
|
||||
let template = parser
|
||||
.parse(template_str)
|
||||
.map_err(|e| anyhow!("Failed to parse extractor template: {}", e))?;
|
||||
|
|
@ -238,6 +241,15 @@ fn render_extractor(
|
|||
}
|
||||
}
|
||||
|
||||
fn truncate_with_ellipsis(input: &str, max_chars: usize) -> String {
|
||||
let truncated: String = input.chars().take(max_chars).collect();
|
||||
if input.chars().count() > max_chars {
|
||||
format!("{}...", truncated)
|
||||
} else {
|
||||
input.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract a value from an HTTP response using the specified extractor.
|
||||
fn extract_value_from_response(
|
||||
extractor: &ResponseExtractor,
|
||||
|
|
@ -338,10 +350,11 @@ async fn execute_http_revocation(
|
|||
let headers = response.headers().clone();
|
||||
let body = response.text().await.context("Failed to read response body")?;
|
||||
|
||||
debug!("Revocation response status: {}", status);
|
||||
debug!("Revocation response body: {}", body);
|
||||
let display_body = truncate_with_ellipsis(&body, 500);
|
||||
let body_len = body.chars().count();
|
||||
|
||||
let display_body = if body.len() > 500 { format!("{}...", &body[..500]) } else { body.clone() };
|
||||
debug!("Revocation response status: {}", status);
|
||||
debug!("Revocation response body (len={}): {}", body_len, display_body);
|
||||
|
||||
let matchers = http_revocation
|
||||
.request
|
||||
|
|
@ -404,8 +417,11 @@ async fn execute_revocation_step(
|
|||
.await
|
||||
.with_context(|| format!("Failed to read response body for {}", step_name))?;
|
||||
|
||||
let display_body = truncate_with_ellipsis(&body, 500);
|
||||
let body_len = body.chars().count();
|
||||
|
||||
debug!("Step {} response status: {}", step_number, status);
|
||||
debug!("Step {} response body: {}", step_number, body);
|
||||
debug!("Step {} response body (len={}): {}", step_number, body_len, display_body);
|
||||
|
||||
// Extract variables from the response if configured
|
||||
if let Some(extractors) = &step.extract {
|
||||
|
|
@ -437,7 +453,7 @@ async fn execute_revocation_step(
|
|||
step_number,
|
||||
e,
|
||||
status,
|
||||
body
|
||||
display_body
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -481,8 +497,7 @@ async fn execute_multi_step_revocation(
|
|||
|
||||
if is_final_step {
|
||||
// Final step: validate response to determine success
|
||||
let display_body =
|
||||
if body.len() > 500 { format!("{}...", &body[..500]) } else { body.clone() };
|
||||
let display_body = truncate_with_ellipsis(&body, 500);
|
||||
|
||||
let matchers = step
|
||||
.request
|
||||
|
|
@ -1310,4 +1325,23 @@ mod tests {
|
|||
_ => panic!("Expected JsonPath variant"),
|
||||
}
|
||||
}
|
||||
|
||||
// ---- truncate_with_ellipsis ----
|
||||
|
||||
#[test]
|
||||
fn truncate_with_ellipsis_no_truncation() {
|
||||
let input = "ok";
|
||||
let output = truncate_with_ellipsis(input, 500);
|
||||
assert_eq!(output, input);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncate_with_ellipsis_handles_unicode() {
|
||||
let input = "é".repeat(501);
|
||||
let output = truncate_with_ellipsis(&input, 500);
|
||||
|
||||
assert!(output.ends_with("..."));
|
||||
assert_eq!(output.chars().count(), 503);
|
||||
assert!(output.chars().take(500).all(|ch| ch == 'é'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -669,7 +669,8 @@ impl DetailsReporter {
|
|||
const MAX_RESPONSE_LENGTH: usize = 512;
|
||||
let truncated_body: String =
|
||||
validation_body_str.chars().take(MAX_RESPONSE_LENGTH).collect();
|
||||
let ellipsis = if validation_body_str.len() > MAX_RESPONSE_LENGTH { "..." } else { "" };
|
||||
let ellipsis =
|
||||
if validation_body_str.chars().count() > MAX_RESPONSE_LENGTH { "..." } else { "" };
|
||||
format!("{}{}", truncated_body, ellipsis)
|
||||
};
|
||||
|
||||
|
|
@ -1323,6 +1324,20 @@ mod tests {
|
|||
(report_match, blob_path)
|
||||
}
|
||||
|
||||
fn build_validation_response(validation_body: &str, full_response: bool) -> String {
|
||||
let temp = tempdir().unwrap();
|
||||
let datastore =
|
||||
Arc::new(Mutex::new(findings_store::FindingsStore::new(temp.path().to_path_buf())));
|
||||
let reporter = DetailsReporter { datastore, styles: Styles::new(false), only_valid: false };
|
||||
|
||||
let (report_match, _) = sample_report_match(validation_body, StatusCode::OK.as_u16(), true);
|
||||
let mut scan_args = sample_scan_args();
|
||||
scan_args.full_validation_response = full_response;
|
||||
|
||||
let record = reporter.build_finding_record(&report_match, &scan_args);
|
||||
record.finding.validation.response
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_finding_record_uses_git_blob_path() {
|
||||
let temp = tempdir().unwrap();
|
||||
|
|
@ -1370,6 +1385,30 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validation_response_truncates_when_flag_off() {
|
||||
let body = "a".repeat(513);
|
||||
let response = build_validation_response(&body, false);
|
||||
assert_eq!(response, format!("{}...", "a".repeat(512)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validation_response_full_when_flag_on() {
|
||||
let body = "a".repeat(513);
|
||||
let response = build_validation_response(&body, true);
|
||||
assert_eq!(response, body);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validation_response_truncation_counts_chars() {
|
||||
let body = "é".repeat(513);
|
||||
let response = build_validation_response(&body, false);
|
||||
|
||||
assert!(response.ends_with("..."));
|
||||
assert_eq!(response.chars().count(), 515);
|
||||
assert!(response.chars().take(512).all(|ch| ch == 'é'));
|
||||
}
|
||||
|
||||
use super::build_git_urls;
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue