Skip to content
This repository has been archived by the owner on Dec 25, 2023. It is now read-only.

MSBuild log generated by StyleCop throws ArgumentOutOfRangeException #80

Closed
brianfeucht opened this issue Mar 11, 2019 · 15 comments
Closed
Labels
Milestone

Comments

@brianfeucht
Copy link
Contributor

The following Xml MSBuild log causes an System.ArgumentOutOfRangeException : startIndex cannot be larger than length of string.

<?xml version="1.0" encoding="utf-8"?>
<build started="3/11/2019 22:29:45">
  <warning code="SA1633" file="File.cs" line="1" column="1" started="3/11/2019 22:29:59"><![CDATA[The file header is missing or not located at the top of the file.]]></warning>
</build>
@brianfeucht
Copy link
Contributor Author

@pascalberger
Copy link
Member

@brianfeucht Thanks for the report and test case.

Can you create a PR with the test case. Then I can implement the fix for this on top of it on your branch (or you can of course also directly provide the implementation in the PR if you want)

@brianfeucht
Copy link
Contributor Author

@pascalberger PR created.

I may get time to implement a fix today, but poking at it last night it wasn't 100% clear the best way to achieve that yet.

It is throwing due to the repository URL being longer than the local file path at

return filePath.Substring(repositorySettings.RepositoryRoot.FullPath.Length);

I think this code would need to check that the string starts with the repository url before doing the substring. However, we'd need to standardize the path separators before doing as one string has / and the other has \\

@pascalberger
Copy link
Member

@brianfeucht On which OS are you running it?

In my environment test case works as expected:

  1. It tries to read the file from the logfile:
    if (!this.TryGetFile(warning, repositorySettings, out string fileName))
  2. It won't find a parent compile task so it skips this part and file name is just File.cs:
    var parentFileAttr = warning.Parent?.Attribute("file");
    if (parentFileAttr != null)
    {
    var compileTaskDirectory = System.IO.Path.GetDirectoryName(parentFileAttr.Value);
    fileName = System.IO.Path.Combine(compileTaskDirectory, fileName);
    }
  3. It will validate the file name:
    (result, fileName) = this.ValidateFilePath(fileName, repositorySettings);
  4. There it will see that file is not part of the repository and therefore exit and ignore this warning:
    if (!this.CheckIfFileIsInRepository(filePath, repositorySettings))
    {
    return (false, string.Empty);
    }

The call to the MakeFilePathRelativeToRepositoryRoot method comes after the check if the file is part of the repository and is not called on my environment:

filePath = this.MakeFilePathRelativeToRepositoryRoot(filePath, repositorySettings);

@brianfeucht
Copy link
Contributor Author

I am on Window 10. Running the test via Visual Studio 16.0.0.0 Preview 3 and DotCover

This also fails running via the CAKE script on Powershell using MSBuild

Doing a bit of debugging based on those details:

  1. parentFileAttr is null
  2. CheckIfFileIsInRepository is returning true:
    filePath.IsSubpathOf(repositorySettings.RepositoryRoot.FullPath) returns true
    "File.cs".IsSubpathOf("c:/Source/Cake.Issues.MsBuild") returns true

@pascalberger
Copy link
Member

Interesting, CheckIfFileIsInRepository, or rather the IsSubpathOf call, should return false (and does on my machine).

@pascalberger
Copy link
Member

On Azure Pipelines the test also fails because it doesn't return an issue and not with an ArgumentOutOfRangeException.

@pascalberger
Copy link
Member

The only case I see when "File.cs".IsSubpathOf("c:/Source/Cake.Issues.MsBuild") returns true is when the current working directory is c:\Source\Cake.Issues.MsBuild. But I fail to see yet why this happens in your case.

@brianfeucht
Copy link
Contributor Author

When I put a stop point at filePath.IsSubpathOf(repositorySettings.RepositoryRoot.FullPath) and run System.IO.Directory.GetCurrentDirectory() in the intermediate window, I get "C:\\source\\Cake.Issues.MsBuild\\src\\Cake.Issues.MsBuild.Tests\\bin\\Debug\\netcoreapp2.0" 🤔

@brianfeucht
Copy link
Contributor Author

I've been able to track this down further. The issue is indeed related to the working directory.

https://github.com/cake-contrib/Cake.Issues/blob/76456cabb492c60be2932023c5c7c94af9412509/src/Cake.Issues/StringPathExtensions.cs#L71

This appears to prepend the CurrentWorking directory to the file name in the case of relative files. In my build environment this is set to the same as the Repository directory. If I call System.IO.Directory.SetCurrentDirectory to a directory outside my Repository I do not get an exception (giving me a work around for now)

I've updated my PR to hopefully make this reproduce for you.

@pascalberger
Copy link
Member

pascalberger commented Mar 14, 2019

Yeah, it's caused by the working directory since Path.GetFullPath is used.

The point which I don't understand is why you're running into this issue, or is c:\Source\Cake.Issues.MsBuild your actual path where you have cloned the repo to?

@brianfeucht
Copy link
Contributor Author

Yes, I've cloned my repo to c:\Source\Cake.Issues.MsBuild

@pascalberger
Copy link
Member

@brianfeucht I've updated #81 to contain a fix for the issue. Can you please test it and report back if it solves your issue.

If it works for you I'll merge the PR and create a release

@brianfeucht
Copy link
Contributor Author

@pascalberger I have confirmed this change resolves the issue in my code base where I first ran into it. 🍻 thank you!

pascalberger added a commit that referenced this issue Mar 18, 2019
(GH-80) MSBuild log generated by StyleCop throws ArgumentOutOfRangeException
@pascalberger
Copy link
Member

pascalberger commented Mar 18, 2019

@brianfeucht Release 0.6.3 is now building and should be available soon on nuget.org

Thanks for reporting this and helping tracking it down. Really appreciated 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants