Skip to content

Commit 39d5465

Browse files
committed
improve error handling when parsing XML
1 parent d5cc0ca commit 39d5465

File tree

4 files changed

+45
-37
lines changed

4 files changed

+45
-37
lines changed

cpp-linter/src/clang_tools/clang_format.rs

+26-15
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ pub fn run_clang_format(
9494
}
9595
let file_name = file.name.to_string_lossy().to_string();
9696
cmd.arg(file.name.to_path_buf().as_os_str());
97-
let mut patched = None;
98-
if clang_params.format_review {
97+
let patched = if !clang_params.format_review {
98+
None
99+
} else {
99100
logs.push((
100101
Level::Info,
101102
format!(
@@ -112,12 +113,12 @@ pub fn run_clang_format(
112113
.join(" ")
113114
),
114115
));
115-
patched = Some(
116+
Some(
116117
cmd.output()
117118
.with_context(|| format!("Failed to get fixes from clang-format: {file_name}"))?
118119
.stdout,
119-
);
120-
}
120+
)
121+
};
121122
cmd.arg("--output-replacements-xml");
122123
logs.push((
123124
log::Level::Info,
@@ -142,16 +143,19 @@ pub fn run_clang_format(
142143
),
143144
));
144145
}
145-
if output.stdout.is_empty() {
146-
return Ok(logs);
147-
}
148-
let xml = String::from_utf8(output.stdout).with_context(|| {
149-
format!("XML output from clang-format was not UTF-8 encoded: {file_name}")
150-
})?;
151-
let mut format_advice = quick_xml::de::from_str::<FormatAdvice>(&xml).unwrap_or(FormatAdvice {
152-
replacements: vec![],
153-
patched: None,
154-
});
146+
let mut format_advice = if !output.stdout.is_empty() {
147+
let xml = String::from_utf8(output.stdout).with_context(|| {
148+
format!("XML output from clang-format was not UTF-8 encoded: {file_name}")
149+
})?;
150+
quick_xml::de::from_str::<FormatAdvice>(&xml).with_context(|| {
151+
format!("Failed to parse XML output from clang-format for {file_name}")
152+
})?
153+
} else {
154+
FormatAdvice {
155+
replacements: vec![],
156+
patched: None,
157+
}
158+
};
155159
format_advice.patched = patched;
156160
if !format_advice.replacements.is_empty() {
157161
let original_contents = fs::read(&file.name).with_context(|| {
@@ -185,6 +189,13 @@ pub fn run_clang_format(
185189
mod tests {
186190
use super::{summarize_style, FormatAdvice, Replacement};
187191

192+
#[test]
193+
fn parse_blank_xml() {
194+
let xml = String::new();
195+
let result = quick_xml::de::from_str::<FormatAdvice>(&xml);
196+
assert!(result.is_err());
197+
}
198+
188199
#[test]
189200
fn parse_xml() {
190201
let xml_raw = r#"<?xml version='1.0'?>

cpp-linter/src/clang_tools/clang_tidy.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,17 @@ pub fn run_clang_tidy(
276276
cmd.args(["--line-filter", filter.as_str()]);
277277
}
278278
}
279-
let mut original_content = None;
280-
if clang_params.tidy_review {
279+
let original_content = if !clang_params.tidy_review {
280+
None
281+
} else {
281282
cmd.arg("--fix-errors");
282-
original_content = Some(fs::read_to_string(&file.name).with_context(|| {
283+
Some(fs::read_to_string(&file.name).with_context(|| {
283284
format!(
284285
"Failed to cache file's original content before applying clang-tidy changes: {}",
285286
file_name.clone()
286287
)
287-
})?);
288-
}
288+
})?)
289+
};
289290
if !clang_params.style.is_empty() {
290291
cmd.args(["--format-style", clang_params.style.as_str()]);
291292
}

cpp-linter/src/clang_tools/mod.rs

+12-16
Original file line numberDiff line numberDiff line change
@@ -258,20 +258,18 @@ pub struct ReviewComments {
258258
impl ReviewComments {
259259
pub fn summarize(&self, clang_versions: &ClangVersions) -> String {
260260
let mut body = format!("{COMMENT_MARKER}## Cpp-linter Review\n");
261-
for t in 0u8..=1 {
261+
for t in 0_usize..=1 {
262262
let mut total = 0;
263263
let (tool_name, tool_version) = if t == 0 {
264264
("clang-format", clang_versions.format_version.as_ref())
265265
} else {
266266
("clang-tidy", clang_versions.tidy_version.as_ref())
267267
};
268-
269-
let tool_total = if let Some(total) = self.tool_total[t as usize] {
270-
total
271-
} else {
272-
// review was not requested from this tool or the tool was not used at all
268+
if tool_version.is_none() {
269+
// this tool was not used at all
273270
continue;
274-
};
271+
}
272+
let tool_total = self.tool_total[t].unwrap_or_default();
275273

276274
// If the tool's version is unknown, then we don't need to output this line.
277275
// NOTE: If the tool was invoked at all, then the tool's version shall be known.
@@ -295,11 +293,11 @@ impl ReviewComments {
295293
.as_str(),
296294
);
297295
}
298-
if !self.full_patch[t as usize].is_empty() {
296+
if !self.full_patch[t].is_empty() {
299297
body.push_str(
300298
format!(
301299
"\n<details><summary>Click here for the full {tool_name} patch</summary>\n\n```diff\n{}```\n\n</details>\n",
302-
self.full_patch[t as usize]
300+
self.full_patch[t]
303301
).as_str()
304302
);
305303
} else {
@@ -370,8 +368,7 @@ pub trait MakeSuggestions {
370368
patch: &mut Patch,
371369
summary_only: bool,
372370
) -> Result<()> {
373-
let tool_name = self.get_tool_name();
374-
let is_tidy_tool = tool_name == "clang-tidy";
371+
let is_tidy_tool = (&self.get_tool_name() == "clang-tidy") as usize;
375372
let hunks_total = patch.num_hunks();
376373
let mut hunks_in_patch = 0u32;
377374
let file_name = file_obj
@@ -384,13 +381,13 @@ pub trait MakeSuggestions {
384381
.to_buf()
385382
.with_context(|| "Failed to convert patch to byte array")?
386383
.to_vec();
387-
review_comments.full_patch[is_tidy_tool as usize].push_str(
384+
review_comments.full_patch[is_tidy_tool].push_str(
388385
String::from_utf8(patch_buf.to_owned())
389386
.with_context(|| format!("Failed to convert patch to string: {file_name}"))?
390387
.as_str(),
391388
);
392-
review_comments.tool_total[is_tidy_tool as usize].get_or_insert(0);
393389
if summary_only {
390+
review_comments.tool_total[is_tidy_tool].get_or_insert(0);
394391
return Ok(());
395392
}
396393
for hunk_id in 0..hunks_total {
@@ -447,9 +444,8 @@ pub trait MakeSuggestions {
447444
review_comments.comments.push(comment);
448445
}
449446
}
450-
review_comments.tool_total[is_tidy_tool as usize] = Some(
451-
review_comments.tool_total[is_tidy_tool as usize].unwrap_or_default() + hunks_in_patch,
452-
);
447+
review_comments.tool_total[is_tidy_tool] =
448+
Some(review_comments.tool_total[is_tidy_tool].unwrap_or_default() + hunks_in_patch);
453449
Ok(())
454450
}
455451
}

cpp-linter/src/common_fs/file_filter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl FileFilter {
111111
|| (pat.is_dir() && file_name.starts_with(pat))
112112
{
113113
log::debug!(
114-
"file {file_name:?} is in {}ignored with domain {pattern:?}.",
114+
"file {file_name:?} is {}ignored with domain {pattern:?}.",
115115
if is_ignored { "" } else { "not " }
116116
);
117117
return true;

0 commit comments

Comments
 (0)