cyclonedx-dotnet
cyclonedx-dotnet copied to clipboard
System.IO.InvalidDataException: Central Directory corrupt with 2.4.1
Hi,
using version 2.4.1 some of our builds are failing due to a System.IO.InvalidDataException
exception. Those builds were working using version 2.3.0 and are still working if we fix the version to 2.3.0. We observed this exception in two different projects for different dependencies:
Retrieving GitHub license for repository nspec/NSpec and ref master
Unhandled exception. System.IO.InvalidDataException: Central Directory corrupt.
---> System.IO.IOException: An attempt was made to move the position before the beginning of the stream.
at System.IO.MemoryStream.Seek(Int64 offset, SeekOrigin loc)
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
--- End of inner exception stack trace ---
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
at System.IO.Compression.ZipArchive.Init(Stream stream, ZipArchiveMode mode, Boolean leaveOpen)
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen, Encoding entryNameEncoding)
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 315
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 315
at CycloneDX.Services.NugetV3Service.GetComponentAsync(String name, String version, Nullable`1 scope) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 231
at CycloneDX.Services.NugetV3Service.GetComponentAsync(NugetPackage nugetPackage) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 322
at CycloneDX.Program.OnExecuteAsync(CommandLineApplication app) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 281
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.InvokeAsync(MethodInfo method, Object instance, Object[] arguments)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.OnExecute(ConventionContext context, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.<>c__DisplayClass0_0.<<Apply>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync[TApp](CommandLineContext context, CancellationToken cancellationToken)
at CycloneDX.Program.Main(String[] args) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 130
at CycloneDX.Program.<Main>(String[] args)
and
Retrieving GitHub license for repository IdentityServer/IdentityServer3.AccessTokenValidation and ref master
Unhandled exception. System.IO.InvalidDataException: Central Directory corrupt.
---> System.IO.IOException: An attempt was made to move the position before the beginning of the stream.
at System.IO.MemoryStream.Seek(Int64 offset, SeekOrigin loc)
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
--- End of inner exception stack trace ---
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen, Encoding entryNameEncoding)
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen)
at NuGet.Packaging.PackageArchiveReader..ctor(Stream stream, Boolean leaveStreamOpen, IFrameworkNameProvider frameworkProvider, IFrameworkCompatibilityProvider compatibilityProvider)
at NuGet.Packaging.PackageArchiveReader..ctor(Stream stream)
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 273
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 279
at CycloneDX.Services.NugetV3Service.GetComponentAsync(String name, String version, Nullable`1 scope) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 231
at CycloneDX.Services.NugetV3Service.GetComponentAsync(NugetPackage nugetPackage) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 320
at CycloneDX.Program.OnExecuteAsync(CommandLineApplication app) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 281
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.InvokeAsync(MethodInfo method, Object instance, Object[] arguments)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.OnExecute(ConventionContext context, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.<>c__DisplayClass0_0.<<Apply>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync[TApp](CommandLineContext context, CancellationToken cancellationToken)
at CycloneDX.Program.Main(String[] args) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 130
at CycloneDX.Program.<Main>(String[] args)
The builds are running in Azure Pipelines on Linux Build Servers inside Docker containers based on mcr.microsoft.com/dotnet/sdk:3.1
. We tried using mcr.microsoft.com/dotnet/sdk:6.0
as the container image but faced the same error message.
Thank you in advance!
Only occured on the build server (Linux) for us. Worked on local Windows machines. Persisted with 2.5.1
I am getting the same error with versions 2.5.1, 2.6.0, and 2.7.0
» Analyzing: /installkits/mspGisAMR/mspGisAMR.csproj
Attempting to restore packages
Packages restored
File not found: "/installkits/mspGisAMR/obj/project.assets.json", "/installkits/mspGisAMR/mspGisAMR.csproj"
No packages found
Unhandled exception. System.IO.InvalidDataException: Central Directory corrupt.
---> System.IO.IOException: An attempt was made to move the position before the beginning of the stream.
at System.IO.MemoryStream.Seek(Int64 offset, SeekOrigin loc)
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
--- End of inner exception stack trace ---
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen, Encoding entryNameEncoding)
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen)
at NuGet.Packaging.PackageArchiveReader..ctor(Stream stream, Boolean leaveStreamOpen, IFrameworkNameProvider frameworkProvider, IFrameworkCompatibilityProvider compatibilityProvider)
at NuGet.Packaging.PackageArchiveReader..ctor(Stream stream)
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 273
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 279
at CycloneDX.Services.NugetV3Service.GetComponentAsync(String name, String version, Nullable`1 scope) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 157
at CycloneDX.Services.NugetV3Service.GetComponentAsync(NugetPackage nugetPackage) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 320
at CycloneDX.Program.OnExecuteAsync(CommandLineApplication app) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 283
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.InvokeAsync(MethodInfo method, Object instance, Object[] arguments)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.OnExecute(ConventionContext context, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.<>c__DisplayClass0_0.<<Apply>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync[TApp](CommandLineContext context, CancellationToken cancellationToken)
at CycloneDX.Program.Main(String[] args) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 132
at CycloneDX.Program.<Main>(String[] args)
Can't find out why this is happening
In my case, I use an internal NuGet repository for a dotnet restore for some internal packages.
In older versions I didn't need to specify a --url
for cyclonedx as well, but after the 2.4.1 update I started to get this error across projects. I've been updating these projects to specify the NuGet url for our internal repository and they work again after that.
oh wow. That lines up with what I'm seeing. I'll add the --url
param and see what happens
This did not work for me. Even after setting the --url
param, I still get the Central Directory corrupt message. The 2.3.0 docker image does work for me however. So, what's the difference between the 2.4.1 and 2.3.0 versions that would be causing this?
I was having this issue as well within an Azure build pipeline. Our solutions also rely on internal feeds, but supplying the feed in question did not solve the issue directly, although it was definitely a piece of the puzzle. I did however include a nuget restore step on the solution I was building the BOM for before executing the CycloneDX call and that alleviated the problem.
Just as a speculation it seems like this is maybe an issue with having a mix of PackageReference
and package.config
file usage in project files within a solution (as we do). If you follow the error, it's actually being thrown when constructing a ZipArchive
object. Which is done directly in the constructor (ew IMO) of the PackageArchiveReader
class in the NuGet.Packaging code (I believe this is part of the NuGet.Protocol package that CycloneDX is including). It's attempting to Read
an archive based on the stream being set in. If I were to guess, the stream doesn't actually contain the content of the archive because the packages haven't been properly restored, and thus the failure.
I don't know for sure that's what's going on, but doing a restore + including the custom feed url seems to solve this problem for us.
I'm having same issue on debian v11.5
, dotnet SDK v6.0.0
, cyclonedx-dotnet v2.7.0 and v2.6.0
.
Unhandled exception. System.IO.InvalidDataException: Central Directory corrupt.
cyclonedx-dotnet v2.3.0
does work for me.
I'm having same with NuGet package source on windowns.
Retrieving GitHub license for repository starkbank/ecdsa-dotnet - URL: https://api.github.com/repos/starkbank/ecdsa-dotnet/license
Unhandled exception. System.IO.InvalidDataException: Central Directory corrupt.
---> System.IO.IOException: An attempt was made to move the position before the beginning of the stream.
at System.IO.MemoryStream.Seek(Int64 offset, SeekOrigin loc)
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
--- End of inner exception stack trace ---
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen, Encoding entryNameEncoding)
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen)
at NuGet.Packaging.PackageArchiveReader..ctor(Stream stream, Boolean leaveStreamOpen, IFrameworkNameProvider frameworkProvider, IFrameworkCompatibilityProvider compatibilityProvider)
at NuGet.Packaging.PackageArchiveReader..ctor(Stream stream)
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 301
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 307
at CycloneDX.Services.NugetV3Service.GetComponentAsync(String name, String version, Nullable`1 scope) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 157
at CycloneDX.Services.NugetV3Service.GetComponentAsync(NugetPackage nugetPackage) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 348
at CycloneDX.Program.OnExecuteAsync(CommandLineApplication app) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 293
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.InvokeAsync(MethodInfo method, Object instance, Object[] arguments)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.OnExecute(ConventionContext context, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.<>c__DisplayClass0_0.<<Apply>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync[TApp](CommandLineContext context, CancellationToken cancellationToken)
at CycloneDX.Program.Main(String[] args) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 138
at CycloneDX.Program.<Main>(String[] args)
definetly requires a "dotnet restore" and additional url to the internal nuget repo. I am on v2.7.0.
@praaymak thanks for the hint!
So, if the project relies on internal / non-public nugets, cyclondx should give a warning when the --url
parameter is missing.
Same problem here with v2.7.0 on windows. Downgrading to v2.3.0 works.
Same problem on Windows 2022 with version 2.7.0. Not using the github license scan
Found the following local nuget package cache locations:
E:\Cache\NuGet\Packages
» Analyzing: E:\adoagents\agent3\_work\1102\s\src\project.csproj
Unhandled exception. System.IO.InvalidDataException: Central Directory corrupt.
---> System.IO.IOException: An attempt was made to move the position before the beginning of the stream.
at System.IO.MemoryStream.Seek(Int64 offset, SeekOrigin loc)
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
--- End of inner exception stack trace ---
at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen, Encoding entryNameEncoding)
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen)
at NuGet.Packaging.PackageArchiveReader..ctor(Stream stream, Boolean leaveStreamOpen, IFrameworkNameProvider frameworkProvider, IFrameworkCompatibilityProvider compatibilityProvider)
at NuGet.Packaging.PackageArchiveReader..ctor(Stream stream)
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 301
at CycloneDX.Services.NugetV3Service.GetNuspec(String name, String version, String nuspecFilename, FindPackageByIdResource resource) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 307
at CycloneDX.Services.NugetV3Service.GetComponentAsync(String name, String version, Nullable`1 scope) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 157
at CycloneDX.Services.NugetV3Service.GetComponentAsync(NugetPackage nugetPackage) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/NugetV3Service.cs:line 348
at CycloneDX.Program.OnExecuteAsync(CommandLineApplication app) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 293
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.InvokeAsync(MethodInfo method, Object instance, Object[] arguments)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.OnExecute(ConventionContext context, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.<>c__DisplayClass0_0.<<Apply>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync[TApp](CommandLineContext context, CancellationToken cancellationToken)
at CycloneDX.Program.Main(String[] args) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 138
at CycloneDX.Program.<Main>(String[] args)
Can confirm @peterbarendse, seeing the same behaviour.
Did anyone figure out solution for using version 2.7.0 ? I am facing this issue if I run it in Linux VM in azure pipelines as well as local machine but it is working without any issues in my local windows machine, not sure what causing the issue. I also tried to run in windows VMs in azure pipelines, still causing same issue, not sure how it is working locally with windows machine. Did anyone face the similar issue ? Unhandled exception. System.IO.InvalidDataException: Central Directory corrupt. ---> System.IO.IOException: An attempt was made to move the position before the beginning of the stream. at System.IO.MemoryStream.Seek(Int64 offset, SeekOrigin loc) at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory() --- End of inner exception stack trace ---
I have the same error message, and dug some deeper. CycloneDX tries to load the nuspec file from the caches, which succeeds most of the time. If the nuspec file is not in the expected location, it tries to load the nupkg from the web and fails with the ZipArchive error if loading fails.
I found a few reasons why this nuspec might not be found in the cache.
- It appears that some packages carry multiple version number formats. For example packages CuttingEdge.Conditions version 1.2.0 is referenced in packages.config as version 1.2.0.0 . CycloneDX expects this longer version, but it doesn't find the nuspec at C:\Users....nuget\packages\cuttingedge.conditions\1.2.0.0\cuttingedge.conditions.nuspec because the path uses the shorter version number. According to https://learn.microsoft.com/en-us/nuget/concepts/package-versioning#normalized-version-numbers , "a zero in the fourth part of the version number will be omitted".
- Nuget restore (if in your build pipeline before the CycloneDX step) might put the packages in packages folder in the solution, and that's not where CycloneDX searches.
If your packages are from nuget.org, and CycloneDX can retrieve the packages, it can work around this condition. And then you don't see any error, just a delay.
Regarding reason number 2 above: in method DotnetUtilsService.GetPackageCachePaths
I added .\packages
to the list of cache folders to search, and then it successfully loaded the packages. Is that the right solution direction?
I have the same error message, and dug some deeper. CycloneDX tries to load the nuspec file from the caches, which succeeds most of the time. If the nuspec file is not in the expected location, it tries to load the nupkg from the web and fails with the ZipArchive error if loading fails.
I found a few reasons why this nuspec might not be found in the cache.
- It appears that some packages carry multiple version number formats. For example packages CuttingEdge.Conditions version 1.2.0 is referenced in packages.config as version 1.2.0.0 . CycloneDX expects this longer version, but it doesn't find the nuspec at C:\Users....nuget\packages\cuttingedge.conditions\1.2.0.0\cuttingedge.conditions.nuspec because the path uses the shorter version number. According to https://learn.microsoft.com/en-us/nuget/concepts/package-versioning#normalized-version-numbers , "a zero in the fourth part of the version number will be omitted".
- Nuget restore (if in your build pipeline before the CycloneDX step) might put the packages in packages folder in the solution, and that's not where CycloneDX searches.
If your packages are from nuget.org, and CycloneDX can retrieve the packages, it can work around this condition. And then you don't see any error, just a delay.
Regarding reason number 2 above: in method
DotnetUtilsService.GetPackageCachePaths
I added.\packages
to the list of cache folders to search, and then it successfully loaded the packages. Is that the right solution direction?
I like this solution but i like the ability to pass in a cache path much better. We override the default, which is a .NET provided functionality, and it looks like we'll have to work around this by copying our packages to the default package cache location if this isn't offered. (or we can try downgrading it looks like)
We override the default, which is a .NET provided functionality, and it looks like we'll have to work around this by copying our packages to the default package cache location if this isn't offered. (or we can try downgrading it looks like)
CycloneDX-dotnet gets the cache paths using command "dotnet nuget locals global-packages --list" . According to https://learn.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders the global-packages cache location can be controlled through the nuget config file or environment variable. I guess you should be able to point the tool to your own cache this way.
We override the default, which is a .NET provided functionality, and it looks like we'll have to work around this by copying our packages to the default package cache location if this isn't offered. (or we can try downgrading it looks like)
CycloneDX-dotnet gets the cache paths using command "dotnet nuget locals global-packages --list" . According to https://learn.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders the global-packages cache location can be controlled through the nuget config file or environment variable. I guess you should be able to point the tool to your own cache this way.
Arthur,
Ah, great find, I took a look at the code but not deep enough to notice where it obtains that. We'll give that a shot, we should be able to obtain that cache programmatically and then use above to set it into our file before nuget restore. Much better than copying stuff around! Thanks!
-Matt
We override the default, which is a .NET provided functionality, and it looks like we'll have to work around this by copying our packages to the default package cache location if this isn't offered. (or we can try downgrading it looks like)
CycloneDX-dotnet gets the cache paths using command "dotnet nuget locals global-packages --list" . According to https://learn.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders the global-packages cache location can be controlled through the nuget config file or environment variable. I guess you should be able to point the tool to your own cache this way.
Arthur,
Ah, great find, I took a look at the code but not deep enough to notice where it obtains that. We'll give that a shot, we should be able to obtain that cache programmatically and then use above to set it into our file before nuget restore. Much better than copying stuff around! Thanks!
-Matt
Confirmed! This was a great work around, thanks again Arthur!
Same issue here. Setup: Azure DevOps Pipeline, private azure devops Nuget Feed. I do have a dotnet restore step before the cyclonedx step which works fine. however, with newer version it was necessary to provide a --url with the private nuget feed. User/pw was not necessary somehow.
I wonder why it does not pick that up from a nuget config file which is also available containing the URL?
I could reproduce the exception by using a package from a private repository and removing it from the cache folder before running CycloneDX. However, adding(in my case) -u http://localhost:8081/repository/nuget-group/index.json
solved the problem.
Normally you would have everything in the cache after running restore, but it is possible that restore and CycloneDX run in different containers. It seems the nuget library does not automatically read the sources from the config; this might be a potential code change.
Another potential code change would be a custom exception, pointing the user towards providing the -u
parameter.
If there is still anyone who get this error even with -u, please come forward.
I could reproduce the exception by using a package from a private repository and removing it from the cache folder before running CycloneDX. However, adding(in my case)
-u http://localhost:8081/repository/nuget-group/index.json
solved the problem.Normally you would have everything in the cache after running restore, but it is possible that restore and CycloneDX run in different containers. It seems the nuget library does not automatically read the sources from the config; this might be a potential code change.
Another potential code change would be a custom exception, pointing the user towards providing the
-u
parameter.If there is still anyone who get this error even with -u, please come forward.
Are you saying that you solved this by using -u <Path to your local feed>
and this made needing a cache not needed? This is even more desirable a fix because we do containerize our Cyclone DX usage. It would be ideal for us to be able to either restore directly on demand, or just point it to a gathering of the packages we stashed. Please confirm if -u
option is doing what I think it is. Thanks!
Are you saying that you solved this by using -u <Path to your local feed> and this made needing a cache not needed?
It's the other way around. --URL
is used as fallback, when the package cannot be found in the cache.
Which is usually the case, when restore run on another system (e.g. container) and cyclonedx runs with --disable-package-restore
. The "Central Directory Corrupt"-Error indicates that the package couldn't be found in the repository.
-u <Path to your local feed>
No idea if NuGet knows how to handle a path here - often it does. I use a URL. Do you only have a local feed as path and no private NuGet Repository (eg. Nexus) as URL as in my example?
Please confirm if -u option is doing what I think it is. Thanks!
To conclude: If information for a package is not found in the NuGet Cache, then CycloneDX will try to get the information from a NuGet feed. By default, it will try the public Microsoft feed. If -u
is set, it tries to query a feed at the given URL.
Please let me know whether that helps you.
I think that might work for our purposes, I'd love to give it a shot, I'll check if it works. Yes, we use a local directory because we stash the packages we have already fetched in an earlier stage, so we should be able to just point it to there. I'll try to get back next week when I can have a chance to try something. Thanks for the info!
The problem is because because of GetNuspec C:\Repos\cyclonedx-dotnet\CycloneDX\Services\NugetV3Service.cs
> System.Private.CoreLib.dll!System.IO.MemoryStream.Seek(long offset, System.IO.SeekOrigin loc) Line 476 C#
System.IO.Compression.dll!System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory() Line 352 C#
System.IO.Compression.dll!System.IO.Compression.ZipArchive.ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen, System.Text.Encoding entryNameEncoding) Line 179 C#
System.IO.Compression.dll!System.IO.Compression.ZipArchive.ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen) Line 106 C#
NuGet.Packaging.dll!NuGet.Packaging.PackageArchiveReader.PackageArchiveReader(System.IO.Stream stream, bool leaveStreamOpen, NuGet.Frameworks.IFrameworkNameProvider frameworkProvider, NuGet.Frameworks.IFrameworkCompatibilityProvider compatibilityProvider) Unknown
NuGet.Packaging.dll!NuGet.Packaging.PackageArchiveReader.PackageArchiveReader(System.IO.Stream stream) Unknown
CycloneDX.dll!CycloneDX.Services.NugetV3Service.GetNuspec(string name, string version, string nuspecFilename, NuGet.Protocol.Core.Types.FindPackageByIdResource resource) Line 325 C#
The problem is because because of GetNuspec C:\Repos\cyclonedx-dotnet\CycloneDX\Services\NugetV3Service.cs
> System.Private.CoreLib.dll!System.IO.MemoryStream.Seek(long offset, System.IO.SeekOrigin loc) Line 476 C# System.IO.Compression.dll!System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory() Line 352 C# System.IO.Compression.dll!System.IO.Compression.ZipArchive.ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen, System.Text.Encoding entryNameEncoding) Line 179 C# System.IO.Compression.dll!System.IO.Compression.ZipArchive.ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen) Line 106 C# NuGet.Packaging.dll!NuGet.Packaging.PackageArchiveReader.PackageArchiveReader(System.IO.Stream stream, bool leaveStreamOpen, NuGet.Frameworks.IFrameworkNameProvider frameworkProvider, NuGet.Frameworks.IFrameworkCompatibilityProvider compatibilityProvider) Unknown NuGet.Packaging.dll!NuGet.Packaging.PackageArchiveReader.PackageArchiveReader(System.IO.Stream stream) Unknown CycloneDX.dll!CycloneDX.Services.NugetV3Service.GetNuspec(string name, string version, string nuspecFilename, NuGet.Protocol.Core.Types.FindPackageByIdResource resource) Line 325 C#
@fbrunetgirard After all the editing there is not much left of your response. Are you saying it worked in your case when you changed the MemorySteam to a FileStream?
The problem is because because of GetNuspec C:\Repos\cyclonedx-dotnet\CycloneDX\Services\NugetV3Service.cs
> System.Private.CoreLib.dll!System.IO.MemoryStream.Seek(long offset, System.IO.SeekOrigin loc) Line 476 C# System.IO.Compression.dll!System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory() Line 352 C# System.IO.Compression.dll!System.IO.Compression.ZipArchive.ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen, System.Text.Encoding entryNameEncoding) Line 179 C# System.IO.Compression.dll!System.IO.Compression.ZipArchive.ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen) Line 106 C# NuGet.Packaging.dll!NuGet.Packaging.PackageArchiveReader.PackageArchiveReader(System.IO.Stream stream, bool leaveStreamOpen, NuGet.Frameworks.IFrameworkNameProvider frameworkProvider, NuGet.Frameworks.IFrameworkCompatibilityProvider compatibilityProvider) Unknown NuGet.Packaging.dll!NuGet.Packaging.PackageArchiveReader.PackageArchiveReader(System.IO.Stream stream) Unknown CycloneDX.dll!CycloneDX.Services.NugetV3Service.GetNuspec(string name, string version, string nuspecFilename, NuGet.Protocol.Core.Types.FindPackageByIdResource resource) Line 325 C#
@fbrunetgirard After all the editing there is not much left of your response. Are you saying it worked in your case when you changed the MemorySteam to a FileStream?
Im trying to test more im still not sure how to figure out if this is because of a private nuget feed or not The memory stream to file doesnt give me good result yet, since it empty, at least im able to reproduce it
FileStream file = new FileStream(path, FileMode.CreateNew);
packageStream.WriteTo(file);
file.Close();
Some packages cannot be found inside my private nuget repo (proget) and crash the tool but they are from nuget.org It was worst when i did not use the -u argument and im using -dpr
So far it doesnt seem to read nuget.config file as well
I merged those PRs from Dependabot yesterday. There is one issue I want to fix and then I will release a new version. Hopefully this is solved then. I'd appreciate a short feedback after.
I merged those PRs from Dependabot yesterday. There is one issue I want to fix and then I will release a new version. Hopefully this is solved then. I'd appreciate a short feedback after.
Great thanks!
Still invalid package can mess the whole thing up, or when the private feed is not link to nuget.org Nuget.config will be great to be use instead of specifying one nuget url only
Files doesnt seem cached as well when calling cyclonedx multiple time or same projects have the same reference.
I done more investigation and the package is found using the cmd
$Username = 'MyUsername'
$Password = ConvertTo-SecureString 'password' -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential($Username, $Password)
$package = "jQuery.vsdoc"
$version = "1.6"
Find-Package $package -RequiredVersion $version -Source 'myrepo' -Credential $Credential
Name Version Source Summary
jQuery.vsdoc 1.6 MSNUGET vsdoc files for Visual Studio IntelliS...
But crashing using the sdk `` `using NuGet.Common; using NuGet.Configuration; using NuGet.Packaging; using NuGet.Protocol; using NuGet.Protocol.Core.Types; using NuGet.Versioning;
string url = "url"; string username = "username"; string password = "password"; ILogger logger = NullLogger.Instance; CancellationToken cancellationToken = CancellationToken.None;
SourceCacheContext cache = new SourceCacheContext();
PackageSource packageSource = new PackageSource(url); packageSource.Credentials = new PackageSourceCredential(url,username, password, true, null);
SourceRepository repository = Repository.Factory.GetCoreV3(packageSource); FindPackageByIdResource resource = await repository.GetResourceAsync<FindPackageByIdResource>();
string packageId = "jQuery.vsdoc"; NuGetVersion packageVersion = new NuGetVersion("1.6"); using MemoryStream packageStream = new MemoryStream();
await resource.CopyNupkgToStreamAsync( packageId, packageVersion, packageStream, cache, logger, cancellationToken);
Console.WriteLine($"Downloaded package {packageId} {packageVersion}");
using PackageArchiveReader packageReader = new PackageArchiveReader(packageStream); NuspecReader nuspecReader = await packageReader.GetNuspecReaderAsync(cancellationToken);`