Skip to content

Fix dropped NuGet vulnerability warnings (NU1902/NU1903) from MSBuild Exec output#1535

Open
Dipanshusinghh wants to merge 2 commits into
jenkinsci:mainfrom
Dipanshusinghh:fix/msbuild-exec-warnings-1512
Open

Fix dropped NuGet vulnerability warnings (NU1902/NU1903) from MSBuild Exec output#1535
Dipanshusinghh wants to merge 2 commits into
jenkinsci:mainfrom
Dipanshusinghh:fix/msbuild-exec-warnings-1512

Conversation

@Dipanshusinghh

@Dipanshusinghh Dipanshusinghh commented Jun 15, 2026

Copy link
Copy Markdown

Fixes #1512

MSBuild's Exec task prefixes output lines with the task name (e.g. EXEC)
when there's no file path. The parser treated this the same as an .exe
name and dropped it, so NuGet warnings (NU1902/NU1903) never showed up
in the Warnings plugin.

Split isToolName into two cases - exe/placeholder names get dropped as
before, bare task names (EXEC, NMAKE, CSC etc.) now create an issue with
fileName "-" so the warning is visible.

Added issue1512.txt with the warnings from the bug report and a new test,
plus updated the existing 56613 tests since they now expect these warnings
to come through.

@github-actions
github-actions Bot requested a review from uhafner June 15, 2026 14:41
@Dipanshusinghh
Dipanshusinghh force-pushed the fix/msbuild-exec-warnings-1512 branch 3 times, most recently from b4c99cc to 5e64447 Compare June 15, 2026 16:54
@uhafner uhafner added the bug Bugs or performance problems label Jun 16, 2026
Comment thread src/main/java/edu/hm/hafner/analysis/parser/MsBuildParser.java Fixed
@Dipanshusinghh
Dipanshusinghh force-pushed the fix/msbuild-exec-warnings-1512 branch 4 times, most recently from 7ec9942 to 98fbf20 Compare June 17, 2026 11:40
@KalleOlaviNiemitalo

KalleOlaviNiemitalo commented Jun 18, 2026

Copy link
Copy Markdown

Split isToolName into two cases - exe/placeholder names get dropped as
before, bare task names (EXEC, NMAKE, CSC etc.) now create an issue with
fileName "-" so the warning is visible.

What is the use case for dropping diagnostics with exe/placeholder names? I mean, why would one want to drop those?

@github-actions

Copy link
Copy Markdown

☀️   Quality Monitor

Tests

   JUnit   Unit Tests: ❌ unstable — 1 failed $\color{red}{\textsf{(+1)}}$, 1915 passed $\color{green}{\textsf{(+1)}}$, 2 skipped $\textsf{(±0)}$
   ⛔   Architecture Tests: ✅ successful — 12 passed $\textsf{(±0)}$

Coverage for New Code

   〰️   Line Coverage: 100.00% — perfect 🎉
   ➰   Branch Coverage: 96.67% — 1 missed branches

Coverage for Whole Project

   〰️   Line Coverage: 94.56% $\color{green}{\textsf{(+0.02)}}$ — 510 missed lines
   ➰   Branch Coverage: 88.78% $\color{green}{\textsf{(+0.26)}}$ — 379 missed branches

Style

   CheckStyle   CheckStyle: No warnings $\textsf{(±0)}$
   PMD   PMD: No warnings $\textsf{(±0)}$
   ☕   Java Compiler: No warnings $\textsf{(±0)}$

Bugs

   SpotBugs   SpotBugs: No bugs $\textsf{(±0)}$
   🐛   Error Prone: No bugs $\textsf{(±0)}$

API Problems

   🚫   Revapi: No warnings $\textsf{(±0)}$

Vulnerabilities

   🛡️   OWASP Dependency Check: No vulnerabilities $\textsf{(±0)}$

Software Metrics

   🌀   Cyclomatic Complexity: 3510 (total)
   💭   Cognitive Complexity: 1980 (total)
   ➿   N-Path Complexity: 4739 (total)
   📏   Lines of Code: 33408 (total)
   📝   Non Commenting Source Statements: 12760 (total)
   🔗   Class Cohesion: 100.00% (maximum)
   ⚖️   Weight of Class: 100.00% (maximum)

📌 Reference Results

Delta reports computed against the reference results of 735001a in workflow run 27370332799.

🚦 Quality Gates

Overall Status: ❌ FAILURE

✅ Passed Gates

  • ✅ Line Coverage in New Code: 100.00 >= 90.00
  • ✅ Branch Coverage in New Code: 96.67 >= 90.00
  • ✅ Potential Bugs in Whole Project: 0.00 <= 0.00
  • ✅ Style Violation in Whole Project: 0.00 <= 0.00

❌ Failed Gates

  • ❌ Overall Tests Success Rate: 99.95 >= 100.00

Created by Quality Monitor v4.15.0 (#82d77af). More details are shown in the GitHub Checks Result.

@uhafner uhafner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your PR. It looks like this parser is actually a mess which is hard to maintain. It covers too many cases and workarounds. Maybe we need to split it in the future so we get a dedicate parser for each regexp group.

private boolean isToolName(final String fileName) {
if (StringUtils.isBlank(fileName) || "-".equals(fileName) || "unknown.file".equals(fileName)) {
return true;
// Checks if fileName is a tool name. Returns "-" if bare, null if dropped, or original fileName if real.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please convert to a Javadoc comment.

Also please do not use null as a value in my code if possible. You can return a Optional.empty in that case.

It also makes sense to global replace in this parser "-" with something like NO_SOURCE_FILE.

}

var baseFileName = FilenameUtils.getName(fileName).trim();
var baseFileName = java.util.Objects.requireNonNull(FilenameUtils.getName(fileName));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you check in the beginning, no need to check here.

return true;
// Checks if fileName is a tool name. Returns "-" if bare, null if dropped, or original fileName if real.
@CheckForNull
private String checkToolName(final String fileName) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private String checkToolName(final String fileName) {
private String checkToolName(@CheckForNull final String fileName) {

// Checks if fileName is a tool name. Returns "-" if bare, null if dropped, or original fileName if real.
@CheckForNull
private String checkToolName(final String fileName) {
if ("-".equals(fileName) || "unknown.file".equals(fileName)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make sense to check for null here?

@uhafner

uhafner commented Jun 18, 2026

Copy link
Copy Markdown
Member

Split isToolName into two cases - exe/placeholder names get dropped as
before, bare task names (EXEC, NMAKE, CSC etc.) now create an issue with
fileName "-" so the warning is visible.

What is the use case for dropping diagnostics with exe/placeholder names? I mean, why would one want to drop those?

Maybe it helps to look into the tests and the associated issues. I am not using this parser on my own so I cannot remember when we introduced that.

@Dipanshusinghh
Dipanshusinghh force-pushed the fix/msbuild-exec-warnings-1512 branch from 98fbf20 to 6607240 Compare June 18, 2026 08:20
@github-actions
github-actions Bot requested a review from uhafner June 18, 2026 08:20
When MSBuild's Exec task runs an external tool, it prefixes any output
lines that lack a file name with the task name in upper-case (e.g. EXEC).
isToolName() was treating these the same as executable names (.exe) and
discarding the whole warning via Optional.empty().

This caused NuGet vulnerability warnings (NU1902, NU1903, etc.) to be
silently dropped and never appear in the Jenkins Warnings plugin.

Fix: split the isToolName branch. Executable names (.exe) and pseudo-file
placeholders like <command line option> are still dropped. Bare MSBuild
task names (EXEC, NMAKE, CSC, cl, rs, ...) now produce an issue with
fileName set to '-' so the warning still shows up in the report.

Fixes jenkinsci#1512
@Dipanshusinghh
Dipanshusinghh force-pushed the fix/msbuild-exec-warnings-1512 branch from 6607240 to 057f67b Compare June 18, 2026 08:34
@uhafner

uhafner commented Jun 18, 2026

Copy link
Copy Markdown
Member

Please do not use force push after a review as this discards the history.

private String normalizeFileName(final String fileName, @CheckForNull final String projectDir) {
var concatenated = FilenameUtils.concat(projectDir, fileName);
var normalized = canResolveRelativeFileName(fileName, projectDir)
? StringUtils.defaultString(concatenated, fileName) : fileName;
@Dipanshusinghh

Copy link
Copy Markdown
Author

@uhafner
Thanks for the review! I've applied your feedback and fixed the failing CI tests

@uhafner

uhafner commented Jun 25, 2026

Copy link
Copy Markdown
Member

@uhafner Thanks for the review! I've applied your feedback and fixed the failing CI tests

The tests still fail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Bugs or performance problems

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MSBuild parser skipping tool messages hides important warnings

4 participants