Skip to content

Commit 934f167

Browse files
Copilotskofman1
andcommitted
Fix divide by zero error in ListPackageCommandRunner and add test
Co-authored-by: skofman1 <[email protected]>
1 parent 1dbf217 commit 934f167

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/PackageReferenceCommands/ListPackage/ListPackageCommandRunner.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,9 @@ private async Task<Dictionary<string, List<IPackageSearchMetadata>>> GetPackageM
415415

416416
int maxParallel = listPackageArgs.PackageSources.Any(s => s.IsHttp)
417417
? 8 // Try to be nice to HTTP package sources
418-
: (Environment.ProcessorCount / listPackageArgs.PackageSources.Count) + 1;
418+
: listPackageArgs.PackageSources.Count == 0
419+
? Environment.ProcessorCount + 1 // Fallback when no package sources are configured
420+
: (Environment.ProcessorCount / listPackageArgs.PackageSources.Count) + 1;
419421

420422
await ThrottledForEachAsync(allPackages,
421423
async (packageId, cancellationToken) => await GetPackageVersionsAsync(packageId, listPackageArgs, cancellationToken),

test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/ListPackageCommandRunnerTests.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Generic;
66
using System.IO;
77
using System.Linq;
8+
using System.Reflection;
89
using System.Text;
910
using System.Threading;
1011
using System.Threading.Tasks;
@@ -367,5 +368,59 @@ public void FiltersFrameworkPackagesCollectionWithVulnerableMetadata(
367368
Assert.Equal(includeTransitivePositives ? 1 : 0, allPackages.First().TransitivePackages.Count());
368369
}
369370
}
371+
372+
public class GetPackageMetadataAsyncWithEmptyPackageSources
373+
{
374+
[Fact]
375+
public async Task GetPackageMetadataAsync_WithEmptyPackageSources_DoesNotThrowDivideByZero()
376+
{
377+
// Arrange
378+
var packages = new FrameworkPackages("net40");
379+
var topLevelPackages = new List<InstalledPackageReference>
380+
{
381+
ListPackageTestHelper.CreateInstalledPackageReference(name: "TestPackage")
382+
};
383+
packages.TopLevelPackages = topLevelPackages;
384+
var allPackages = new List<FrameworkPackages> { packages };
385+
386+
var output = new StringBuilder();
387+
var error = new StringBuilder();
388+
using TextWriter consoleOut = new StringWriter(output);
389+
using TextWriter consoleError = new StringWriter(error);
390+
391+
// Create ListPackageArgs with empty packageSources list to trigger the divide by zero scenario
392+
var listPackageArgs = new ListPackageArgs(
393+
path: "",
394+
packageSources: new List<PackageSource>(), // Empty package sources - this would cause divide by zero
395+
frameworks: new List<string>(),
396+
ReportType.Outdated, // This will trigger the code path that calls GetPackageMetadataAsync
397+
new ListPackageConsoleRenderer(consoleOut, consoleError),
398+
includeTransitive: false,
399+
prerelease: false,
400+
highestPatch: false,
401+
highestMinor: false,
402+
auditSources: null,
403+
logger: new Mock<ILogger>().Object,
404+
CancellationToken.None);
405+
406+
var listPackageRunner = new ListPackageCommandRunner();
407+
408+
// Act & Assert - Test the private method using reflection
409+
var getPackageMetadataAsyncMethod = typeof(ListPackageCommandRunner)
410+
.GetMethod("GetPackageMetadataAsync", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
411+
412+
Assert.NotNull(getPackageMetadataAsyncMethod);
413+
414+
// This should not throw DivideByZeroException
415+
Exception exception = await Record.ExceptionAsync(async () =>
416+
{
417+
var task = (Task<Dictionary<string, List<IPackageSearchMetadata>>>)getPackageMetadataAsyncMethod.Invoke(
418+
listPackageRunner, new object[] { allPackages, listPackageArgs });
419+
await task;
420+
});
421+
422+
Assert.Null(exception);
423+
}
424+
}
370425
}
371426
}

0 commit comments

Comments
 (0)