Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ReleaseHistory.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* BUG: Fix error `ERR997.NoValidAnalysisTargets` when scanning symbolic link files.
* BUG: Fix `ERR999.UnhandledEngineException: System.IO.FileNotFoundException: Could not find file` when a file name or directory path contains URL-encoded characters.
* BUG: Fix error `ERR997.NoValidAnalysisTargets` when ambiguous file/directory references are provided to `OrderedFileSpecifier`. Previously, the code required an explicit directory separator to be added to the end of a directory path. Now, the code inspects the file system and assumes that a reference to an existing directory was intended by the user (even without a trailing separator).
* BUG: Fix `ArgumentException: Illegal characters in path` when analysis target URI contains characters that are illegal in the file system.
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.

ArgumentException

This release note doesn't describe the code location where the fix was made.

Copy link
Copy Markdown
Member

@michaelcfanning michaelcfanning May 13, 2025

Choose a reason for hiding this comment

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

You haven't described the method that raises the exception. This means that customers who have a stack frame in an exception might not easily find your note. MultithreadedAnalyzeCommandBase.Run would provide this information. Although you've documented this specific fix, you haven't described the other code locations you changed, which you could add. e.g. ExportRulesMetadataCommandBase.Run and ExportConfigurationCommandBase.Run

* NEW: Allow null archive uri in `MultithreadedZipArchiveArtifactProvider` (which indicates that enumerated artifact paths should not include the base archive).
* NEW: Update `LogTargetParseError(IAnalysisContext, Region, string, Exception)` to include optional exception argument to denote code location where parse error occurred.
* NEW: `MultithreadedAnalyzeCommandBase.EnumerateArtifact` now supports scanning into compressed (OPC) files. Initial support file extensions are: `.apk`, `.appx`, `.appxbundle`, `.docx`, `.epub`, `.jar`, `.msix`, `.msixbundle`, `.odp`, `.ods`, `.odt`, `.onepkg`, `.oxps`, `.pkg`, `.pptx`, `.unitypackage`, `.vsdx`, `.xps`, `.xlsx`, `.zip`.
Expand Down
21 changes: 20 additions & 1 deletion src/Sarif.Driver/Sdk/MultithreadedAnalyzeCommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,26 @@ private async Task<bool> EnumerateArtifact(IEnumeratedArtifact artifact, TContex
return false;
}

string extension = Path.GetExtension(filePath);
string extension;
int lastDotIndex = filePath.LastIndexOf('.');
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.

filePath

you have added lots of code and you didn't add unit tests for this.

if you're going to inline Path.GetExtension, perhaps just grab the actual code (and get rid of the invalid path chars check).

can you please create a helper for this? also, did you look for other occurrences of this issue? i see other uses of Path.GetExtension in the code.

https://referencesource.microsoft.com/#mscorlib/system/io/path.cs,f424e433705aeb09

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

None of the other uses of GetExtension looked like they were problematic to me and none of the telemetry points to any other code.

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.

I'm not yet convinced. The export rules and export config commands look like they could problematic to me as well. By inlining this change here and here only, you have left a non-obvious fix which compromises maintainability (i.e., it's very likely that if this problem is encountered again, a dev might not be aware of what you've done, add a duplicate helper or another inlined fix, etc.).

What I'd suggest is to create a static helper for this rewrite and please add unit tests. Then, add a new entry to IFileSystem for GetExtension and call this helper through IFileSystem everywhere in the code base.


if (lastDotIndex < 0)
{
extension = string.Empty;
}
else
{
int lastSeparatorIndex = filePath.LastIndexOf(Path.PathSeparator);
if (lastSeparatorIndex > lastDotIndex)
{
extension = string.Empty;
}
else
{
extension = filePath.Substring(lastDotIndex);
}
}

if (artifact.Uri.IsAbsoluteUri &&
string.IsNullOrEmpty(artifact.Uri.Query) &&
globalContext.OpcFileExtensions.Contains(extension))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,31 @@ public void AnalyzeCommand_EncodedPaths()
sarifLog.Runs[0].Results.Count.Should().Be(1);
}

[Fact]
public void AnalyzeCommand_IllegalPathCharInURL()
{
var sarifOutput = new StringBuilder();
var command = new TestMultithreadedAnalyzeCommand();
using var writer = new StringWriter(sarifOutput);
var logger = new SarifLogger(writer,
run: new Run { Tool = command.Tool },
levels: BaseLogger.ErrorWarningNote,
kinds: BaseLogger.Fail);

var target = new EnumeratedArtifact(FileSystem.Instance) { Uri = new Uri("http://example.com/some<character>test/bad\"characters\"path.txt"), Contents = "fake content" };

var context = new TestAnalysisContext
{
TargetsProvider = new ArtifactProvider(new[] { target }),
FailureLevels = BaseLogger.ErrorWarningNote,
ResultKinds = BaseLogger.Fail,
Logger = logger,
};

int result = command.Run(options: null, ref context);
result.Should().Be(0);
}

[Fact]
[Trait(TestTraits.WindowsOnly, "true")]
public void AnalyzeCommand_TracesInMemory()
Expand Down
Loading