dependabot-nuget 0.286.0 → 0.287.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -729,6 +729,191 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
729
729
  );
730
730
  }
731
731
 
732
+ [Fact]
733
+ public async Task AnalysisCanContineWhenRegistrationJSONIsMalformed()
734
+ {
735
+ // from a case seen in the wild; a transitive dependency's registration JSON has an invalid `range` property
736
+ // analysis should continue
737
+ var aspNetCoreAppRefPackage = MockNuGetPackage.WellKnownReferencePackage("Microsoft.AspNetCore.App", "net8.0");
738
+ var desktopAppRefPackage = MockNuGetPackage.WellKnownReferencePackage("Microsoft.WindowsDesktop.App", "net8.0");
739
+ var netCoreAppRefPackage = MockNuGetPackage.WellKnownReferencePackage("Microsoft.NETCore.App", "net8.0",
740
+ [
741
+ ("data/FrameworkList.xml", Encoding.UTF8.GetBytes("""
742
+ <FileList TargetFrameworkIdentifier=".NETCoreApp" TargetFrameworkVersion="8.0" FrameworkName="Microsoft.NETCore.App" Name=".NET Runtime">
743
+ </FileList>
744
+ """))
745
+ ]);
746
+ (int, byte[]) TestHttpHandler(string uriString)
747
+ {
748
+ var uri = new Uri(uriString, UriKind.Absolute);
749
+ var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
750
+ switch (uri.PathAndQuery)
751
+ {
752
+ // initial request is good
753
+ case "/index.json":
754
+ return (200, Encoding.UTF8.GetBytes($$"""
755
+ {
756
+ "version": "3.0.0",
757
+ "resources": [
758
+ {
759
+ "@id": "{{baseUrl}}/download",
760
+ "@type": "PackageBaseAddress/3.0.0"
761
+ },
762
+ {
763
+ "@id": "{{baseUrl}}/query",
764
+ "@type": "SearchQueryService"
765
+ },
766
+ {
767
+ "@id": "{{baseUrl}}/registrations",
768
+ "@type": "RegistrationsBaseUrl"
769
+ }
770
+ ]
771
+ }
772
+ """));
773
+ case "/registrations/some.package/index.json":
774
+ return (200, Encoding.UTF8.GetBytes("""
775
+ {
776
+ "count": 1,
777
+ "items": [
778
+ {
779
+ "lower": "1.0.0",
780
+ "upper": "1.1.0",
781
+ "items": [
782
+ {
783
+ "catalogEntry": {
784
+ "listed": true,
785
+ "version": "1.0.0"
786
+ }
787
+ },
788
+ {
789
+ "catalogEntry": {
790
+ "listed": true,
791
+ "version": "1.1.0",
792
+ "dependencyGroups": [
793
+ {
794
+ "dependencies": [
795
+ {
796
+ "id": "Some.Transitive.Dependency",
797
+ "range": "",
798
+ "comment": "The above range is invalid and fails the JSON parse"
799
+ }
800
+ ]
801
+ }
802
+ ]
803
+ }
804
+ }
805
+ ]
806
+ }
807
+ ]
808
+ }
809
+ """));
810
+ case "/download/some.package/index.json":
811
+ return (200, Encoding.UTF8.GetBytes("""
812
+ {
813
+ "versions": [
814
+ "1.0.0",
815
+ "1.1.0"
816
+ ]
817
+ }
818
+ """));
819
+ case "/download/some.package/1.0.0/some.package.1.0.0.nupkg":
820
+ return (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0").GetZipStream().ReadAllBytes());
821
+ case "/download/some.package/1.1.0/some.package.1.1.0.nupkg":
822
+ return (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.1.0", "net8.0").GetZipStream().ReadAllBytes());
823
+ case "/download/microsoft.aspnetcore.app.ref/index.json":
824
+ return (200, Encoding.UTF8.GetBytes($$"""
825
+ {
826
+ "versions": [
827
+ "{{aspNetCoreAppRefPackage.Version}}"
828
+ ]
829
+ }
830
+ """));
831
+ case "/download/microsoft.netcore.app.ref/index.json":
832
+ return (200, Encoding.UTF8.GetBytes($$"""
833
+ {
834
+ "versions": [
835
+ "{{netCoreAppRefPackage.Version}}"
836
+ ]
837
+ }
838
+ """));
839
+ case "/download/microsoft.windowsdesktop.app.ref/index.json":
840
+ return (200, Encoding.UTF8.GetBytes($$"""
841
+ {
842
+ "versions": [
843
+ "{{desktopAppRefPackage.Version}}"
844
+ ]
845
+ }
846
+ """));
847
+ default:
848
+ if (uri.PathAndQuery == $"/download/microsoft.aspnetcore.app.ref/{aspNetCoreAppRefPackage.Version}/microsoft.aspnetcore.app.ref.{aspNetCoreAppRefPackage.Version}.nupkg")
849
+ {
850
+ return (200, aspNetCoreAppRefPackage.GetZipStream().ReadAllBytes());
851
+ }
852
+
853
+ if (uri.PathAndQuery == $"/download/microsoft.netcore.app.ref/{netCoreAppRefPackage.Version}/microsoft.netcore.app.ref.{netCoreAppRefPackage.Version}.nupkg")
854
+ {
855
+ return (200, netCoreAppRefPackage.GetZipStream().ReadAllBytes());
856
+ }
857
+
858
+ if (uri.PathAndQuery == $"/download/microsoft.windowsdesktop.app.ref/{desktopAppRefPackage.Version}/microsoft.windowsdesktop.app.ref.{desktopAppRefPackage.Version}.nupkg")
859
+ {
860
+ return (200, desktopAppRefPackage.GetZipStream().ReadAllBytes());
861
+ }
862
+
863
+ // nothing else is found
864
+ return (404, Encoding.UTF8.GetBytes("{}"));
865
+ };
866
+ }
867
+ using var http = TestHttpServer.CreateTestServer(TestHttpHandler);
868
+ await TestAnalyzeAsync(
869
+ extraFiles:
870
+ [
871
+ ("NuGet.Config", $"""
872
+ <configuration>
873
+ <packageSources>
874
+ <clear />
875
+ <add key="package_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
876
+ </packageSources>
877
+ </configuration>
878
+ """)
879
+ ],
880
+ discovery: new()
881
+ {
882
+ Path = "/",
883
+ Projects =
884
+ [
885
+ new()
886
+ {
887
+ FilePath = "./project.csproj",
888
+ TargetFrameworks = ["net8.0"],
889
+ Dependencies =
890
+ [
891
+ new("Some.Package", "1.0.0", DependencyType.PackageReference),
892
+ ]
893
+ }
894
+ ]
895
+ },
896
+ dependencyInfo: new()
897
+ {
898
+ Name = "Some.Package",
899
+ Version = "1.0.0",
900
+ IgnoredVersions = [],
901
+ IsVulnerable = false,
902
+ Vulnerabilities = [],
903
+ },
904
+ expectedResult: new()
905
+ {
906
+ CanUpdate = true,
907
+ UpdatedVersion = "1.1.0",
908
+ VersionComesFromMultiDependencyProperty = false,
909
+ UpdatedDependencies =
910
+ [
911
+ new("Some.Package", "1.1.0", DependencyType.Unknown, TargetFrameworks: ["net8.0"]),
912
+ ],
913
+ }
914
+ );
915
+ }
916
+
732
917
  [Fact]
733
918
  public async Task ResultFileHasCorrectShapeForAuthenticationFailure()
734
919
  {
@@ -835,4 +1020,121 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
835
1020
  }
836
1021
  );
837
1022
  }
1023
+
1024
+ [Fact]
1025
+ public async Task AnalysisFailsWhenNewerPackageDownloadIsDenied()
1026
+ {
1027
+ static (int, byte[]) TestHttpHandler(string uriString)
1028
+ {
1029
+ var uri = new Uri(uriString, UriKind.Absolute);
1030
+ var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
1031
+ return uri.PathAndQuery switch
1032
+ {
1033
+ // initial request is good
1034
+ "/index.json" => (200, Encoding.UTF8.GetBytes($$"""
1035
+ {
1036
+ "version": "3.0.0",
1037
+ "resources": [
1038
+ {
1039
+ "@id": "{{baseUrl}}/download",
1040
+ "@type": "PackageBaseAddress/3.0.0"
1041
+ },
1042
+ {
1043
+ "@id": "{{baseUrl}}/query",
1044
+ "@type": "SearchQueryService"
1045
+ },
1046
+ {
1047
+ "@id": "{{baseUrl}}/registrations",
1048
+ "@type": "RegistrationsBaseUrl"
1049
+ }
1050
+ ]
1051
+ }
1052
+ """)),
1053
+ // request for package index is good
1054
+ "/registrations/some.package/index.json" => (200, Encoding.UTF8.GetBytes("""
1055
+ {
1056
+ "count": 1,
1057
+ "items": [
1058
+ {
1059
+ "lower": "1.0.0",
1060
+ "upper": "1.1.0",
1061
+ "items": [
1062
+ {
1063
+ "catalogEntry": {
1064
+ "listed": true,
1065
+ "version": "1.0.0"
1066
+ }
1067
+ },
1068
+ {
1069
+ "catalogEntry": {
1070
+ "listed": true,
1071
+ "version": "1.1.0"
1072
+ }
1073
+ }
1074
+ ]
1075
+ }
1076
+ ]
1077
+ }
1078
+ """)),
1079
+ // request for versions is good
1080
+ "/download/some.package/index.json" => (200, Encoding.UTF8.GetBytes("""
1081
+ {
1082
+ "versions": [
1083
+ "1.0.0",
1084
+ "1.1.0"
1085
+ ]
1086
+ }
1087
+ """)),
1088
+ // download of old package is good
1089
+ "/download/some.package/1.0.0/some.package.1.0.0.nupkg" => (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net9.0").GetZipStream().ReadAllBytes()),
1090
+ // download of new package is denied
1091
+ "/download/some.package/1.1.0/some.package.1.1.0.nupkg" => (401, Array.Empty<byte>()),
1092
+ // all other requests are not found
1093
+ _ => (404, Encoding.UTF8.GetBytes("{}")),
1094
+ };
1095
+ }
1096
+ using var http = TestHttpServer.CreateTestServer(TestHttpHandler);
1097
+ await TestAnalyzeAsync(
1098
+ extraFiles:
1099
+ [
1100
+ ("NuGet.Config", $"""
1101
+ <configuration>
1102
+ <packageSources>
1103
+ <clear />
1104
+ <add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
1105
+ </packageSources>
1106
+ </configuration>
1107
+ """)
1108
+ ],
1109
+ discovery: new()
1110
+ {
1111
+ Path = "/",
1112
+ Projects = [
1113
+ new()
1114
+ {
1115
+ FilePath = "./project.csproj",
1116
+ TargetFrameworks = ["net9.0"],
1117
+ Dependencies = [
1118
+ new("Some.Package", "1.0.0", DependencyType.PackageReference),
1119
+ ],
1120
+ }
1121
+ ]
1122
+ },
1123
+ dependencyInfo: new()
1124
+ {
1125
+ Name = "Some.Package",
1126
+ Version = "1.0.0",
1127
+ IgnoredVersions = [],
1128
+ IsVulnerable = false,
1129
+ Vulnerabilities = [],
1130
+ },
1131
+ expectedResult: new()
1132
+ {
1133
+ UpdatedVersion = "1.0.0",
1134
+ CanUpdate = false,
1135
+ VersionComesFromMultiDependencyProperty = false,
1136
+ UpdatedDependencies = [],
1137
+ }
1138
+ );
1139
+ }
838
1140
  }
@@ -107,6 +107,106 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
107
107
  );
108
108
  }
109
109
 
110
+ [Fact]
111
+ public async Task TestDependenciesSeparatedBySemicolon()
112
+ {
113
+ await TestDiscoveryAsync(
114
+ packages:
115
+ [
116
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "9.0.1", "net8.0"),
117
+ MockNuGetPackage.CreateSimplePackage("Some.Package2", "9.0.1", "net8.0"),
118
+ ],
119
+ workspacePath: "src",
120
+ files: new[]
121
+ {
122
+ ("src/project.csproj", """
123
+ <Project Sdk="Microsoft.NET.Sdk">
124
+ <PropertyGroup>
125
+ <TargetFramework>net8.0</TargetFramework>
126
+ <SomePackageVersion>9.0.1</SomePackageVersion>
127
+ </PropertyGroup>
128
+
129
+ <ItemGroup>
130
+ <PackageReference Include="Some.Package;Some.Package2" Version="$(SomePackageVersion)" />
131
+ </ItemGroup>
132
+ </Project>
133
+ """)
134
+ },
135
+ expectedResult: new()
136
+ {
137
+ Path = "src",
138
+ Projects = [
139
+ new()
140
+ {
141
+ FilePath = "project.csproj",
142
+ TargetFrameworks = ["net8.0"],
143
+ ReferencedProjectPaths = [],
144
+ ExpectedDependencyCount = 3,
145
+ Dependencies = [
146
+ new("Microsoft.NET.Sdk", null, DependencyType.MSBuildSdk),
147
+ new("Some.Package", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
148
+ new("Some.Package2", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
149
+ ],
150
+ Properties = [
151
+ new("SomePackageVersion", "9.0.1", "src/project.csproj"),
152
+ new("TargetFramework", "net8.0", "src/project.csproj"),
153
+ ]
154
+ }
155
+ ]
156
+ }
157
+ );
158
+ }
159
+
160
+ [Fact]
161
+ public async Task TestDependenciesSeparatedBySemicolonWithWhitespace()
162
+ {
163
+ await TestDiscoveryAsync(
164
+ packages:
165
+ [
166
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "9.0.1", "net8.0"),
167
+ MockNuGetPackage.CreateSimplePackage("Some.Package2", "9.0.1", "net8.0"),
168
+ ],
169
+ workspacePath: "src",
170
+ files: new[]
171
+ {
172
+ ("src/project.csproj", """
173
+ <Project Sdk="Microsoft.NET.Sdk">
174
+ <PropertyGroup>
175
+ <TargetFramework>net8.0</TargetFramework>
176
+ <SomePackageVersion>9.0.1</SomePackageVersion>
177
+ </PropertyGroup>
178
+
179
+ <ItemGroup>
180
+ <PackageReference Include=" Some.Package ; Some.Package2 " Version="$(SomePackageVersion)" />
181
+ </ItemGroup>
182
+ </Project>
183
+ """)
184
+ },
185
+ expectedResult: new()
186
+ {
187
+ Path = "src",
188
+ Projects = [
189
+ new()
190
+ {
191
+ FilePath = "project.csproj",
192
+ TargetFrameworks = ["net8.0"],
193
+ ReferencedProjectPaths = [],
194
+ ExpectedDependencyCount = 3,
195
+ Dependencies = [
196
+ new("Microsoft.NET.Sdk", null, DependencyType.MSBuildSdk),
197
+ new("Some.Package", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
198
+ new("Some.Package2", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
199
+ ],
200
+ Properties = [
201
+ new("SomePackageVersion", "9.0.1", "src/project.csproj"),
202
+ new("TargetFramework", "net8.0", "src/project.csproj"),
203
+ ]
204
+ }
205
+ ]
206
+ }
207
+ );
208
+ }
209
+
110
210
  [Fact]
111
211
  public async Task TestPackageConfig()
112
212
  {
@@ -375,6 +475,175 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
375
475
  );
376
476
  }
377
477
 
478
+ [Fact]
479
+ public async Task TestRepo_SolutionFileCasingMismatchIsResolved()
480
+ {
481
+ var solutionPath = "solution.sln";
482
+ await TestDiscoveryAsync(
483
+ packages:
484
+ [
485
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "9.0.1", "net8.0"),
486
+ ],
487
+ workspacePath: "",
488
+ files: new[]
489
+ {
490
+ ("src/project.csproj", """
491
+ <Project Sdk="Microsoft.NET.Sdk">
492
+ <PropertyGroup>
493
+ <TargetFrameworks>net7.0;net8.0</TargetFrameworks>
494
+ </PropertyGroup>
495
+
496
+ <ItemGroup>
497
+ <PackageReference Include="Some.Package" />
498
+ </ItemGroup>
499
+ </Project>
500
+ """),
501
+ ("Directory.Build.props", "<Project />"),
502
+ ("Directory.Packages.props", """
503
+ <Project>
504
+ <PropertyGroup>
505
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
506
+ <SomePackageVersion>9.0.1</SomePackageVersion>
507
+ </PropertyGroup>
508
+
509
+ <ItemGroup>
510
+ <PackageVersion Include="Some.Package" Version="$(SomePackageVersion)" />
511
+ </ItemGroup>
512
+ </Project>
513
+ """),
514
+ (solutionPath, """
515
+ Microsoft Visual Studio Solution File, Format Version 12.00
516
+ # Visual Studio 14
517
+ VisualStudioVersion = 14.0.22705.0
518
+ MinimumVisualStudioVersion = 10.0.40219.1
519
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProJect", ".\src\ProJect.csproj", "{782E0C0A-10D3-444D-9640-263D03D2B20C}"
520
+ EndProject
521
+ Global
522
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
523
+ Debug|Any CPU = Debug|Any CPU
524
+ Release|Any CPU = Release|Any CPU
525
+ EndGlobalSection
526
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
527
+ {782E0C0A-10D3-444D-9640-263D03D2B20C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
528
+ {782E0C0A-10D3-444D-9640-263D03D2B20C}.Debug|Any CPU.Build.0 = Debug|Any CPU
529
+ {782E0C0A-10D3-444D-9640-263D03D2B20C}.Release|Any CPU.ActiveCfg = Release|Any CPU
530
+ {782E0C0A-10D3-444D-9640-263D03D2B20C}.Release|Any CPU.Build.0 = Release|Any CPU
531
+ EndGlobalSection
532
+ GlobalSection(SolutionProperties) = preSolution
533
+ HideSolutionNode = FALSE
534
+ EndGlobalSection
535
+ EndGlobal
536
+ """),
537
+ },
538
+ expectedResult: new()
539
+ {
540
+ Path = "",
541
+ ExpectedProjectCount = 2,
542
+ Projects = [
543
+ new()
544
+ {
545
+ FilePath = "src/project.csproj",
546
+ TargetFrameworks = ["net7.0", "net8.0"],
547
+ ExpectedDependencyCount = 2,
548
+ Dependencies = [
549
+ new("Microsoft.NET.Sdk", null, DependencyType.MSBuildSdk),
550
+ new("Some.Package", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net7.0", "net8.0"], IsDirect: true)
551
+ ],
552
+ Properties = [
553
+ new("ManagePackageVersionsCentrally", "true", "Directory.Packages.props"),
554
+ new("SomePackageVersion", "9.0.1", "Directory.Packages.props"),
555
+ new("TargetFrameworks", "net7.0;net8.0", "src/project.csproj"),
556
+ ]
557
+ }
558
+ ],
559
+ DirectoryPackagesProps = new()
560
+ {
561
+ FilePath = "Directory.Packages.props",
562
+ Dependencies = [
563
+ new("Some.Package", "9.0.1", DependencyType.PackageVersion, IsDirect: true)
564
+ ],
565
+ },
566
+ }
567
+ );
568
+ }
569
+
570
+ [Fact]
571
+ public async Task TestDirsProj_CasingMismatchIsResolved()
572
+ {
573
+ var dirsProjPath = "dirs.proj";
574
+ await TestDiscoveryAsync(
575
+ packages:
576
+ [
577
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "9.0.1", "net8.0"),
578
+ ],
579
+ workspacePath: "",
580
+ files: new[]
581
+ {
582
+ ("src/project.csproj", """
583
+ <Project Sdk="Microsoft.NET.Sdk">
584
+ <PropertyGroup>
585
+ <TargetFrameworks>net7.0;net8.0</TargetFrameworks>
586
+ </PropertyGroup>
587
+
588
+ <ItemGroup>
589
+ <PackageReference Include="Some.Package" />
590
+ </ItemGroup>
591
+ </Project>
592
+ """),
593
+ ("Directory.Build.props", "<Project />"),
594
+ ("Directory.Packages.props", """
595
+ <Project>
596
+ <PropertyGroup>
597
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
598
+ <SomePackageVersion>9.0.1</SomePackageVersion>
599
+ </PropertyGroup>
600
+
601
+ <ItemGroup>
602
+ <PackageVersion Include="Some.Package" Version="$(SomePackageVersion)" />
603
+ </ItemGroup>
604
+ </Project>
605
+ """),
606
+ // Introduce a casing difference in the project reference
607
+ (dirsProjPath, """
608
+ <Project>
609
+ <ItemGroup>
610
+ <ProjectReference Include="SRC/PROJECT.CSPROJ" />
611
+ </ItemGroup>
612
+ </Project>
613
+ """)
614
+ },
615
+ expectedResult: new()
616
+ {
617
+ Path = "",
618
+ ExpectedProjectCount = 2,
619
+ Projects = [
620
+ new()
621
+ {
622
+ FilePath = "src/project.csproj",
623
+ TargetFrameworks = ["net7.0", "net8.0"],
624
+ ExpectedDependencyCount = 2,
625
+ Dependencies = [
626
+ new("Microsoft.NET.Sdk", null, DependencyType.MSBuildSdk),
627
+ new("Some.Package", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net7.0", "net8.0"], IsDirect: true)
628
+ ],
629
+ Properties = [
630
+ new("ManagePackageVersionsCentrally", "true", "Directory.Packages.props"),
631
+ new("SomePackageVersion", "9.0.1", "Directory.Packages.props"),
632
+ new("TargetFrameworks", "net7.0;net8.0", "src/project.csproj"),
633
+ ]
634
+ }
635
+ ],
636
+ DirectoryPackagesProps = new()
637
+ {
638
+ FilePath = "Directory.Packages.props",
639
+ Dependencies = [
640
+ new("Some.Package", "9.0.1", DependencyType.PackageVersion, IsDirect: true)
641
+ ],
642
+ },
643
+ }
644
+ );
645
+ }
646
+
378
647
  [Fact]
379
648
  public async Task NonSupportedProjectExtensionsAreSkipped()
380
649
  {