Skip to content

Commit ac8a922

Browse files
[Xamarin.Android.Build.Tasks] make CA2022 an error (#9282)
I was building Xamarin.Android.Build.Tasks and noticed some CA2022 warnings that scared me: src\Xamarin.Android.Build.Tasks\Utilities\AssemblyCompression.cs(77,6): warning CA2022: Avoid inexact read with 'System.IO.FileStream.Read(byte[], int, int)' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2022) src\Xamarin.Android.Build.Tasks\Utilities\MonoAndroidHelper.cs(186,8): warning CA2022: Avoid inexact read with 'System.IO.FileStream.Read(byte[], int, int)' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2022) Some cases like this were actually ok: byte[] publicKey = new byte[stream.Length]; stream.Read (publicKey, 0, publicKey.Length); // ... name.PublicKey = SigningHelper.GetPublicKey (publicKey); Because it uses `stream.Length` for the `byte[]` size, we don't need to use the return value of `Read()`. Looking at another place, however: sourceBytes = bytePool.Rent (checked((int)fi.Length)); // ... fs.Read (sourceBytes, 0, (int)fi.Length); // ... destBytes = bytePool.Rent (LZ4Codec.MaximumOutputSize (sourceBytes.Length)); This actually is a bug, as it rents a `destBytes` array potentially a bit larger than bytes read. This made me think, we should make CA2022 an error and fix them all. I also updated `MonoAndroidHelper.SizeAndContentFileComparer` to just use the `Files.HashFile()` method. This is probably faster than the previous code, anyway.
1 parent 87f1cd6 commit ac8a922

File tree

12 files changed

+39
-83
lines changed

12 files changed

+39
-83
lines changed

.editorconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public
215215
# Code files
216216
[*.{cs,vb}]
217217

218+
dotnet_diagnostic.CA2022.severity = error # Avoid inexact read with 'System.IO.FileStream.Read(byte[], int, int)'
218219
dotnet_diagnostic.CA2153.severity = error # Do Not Catch Corrupted State Exceptions
219220
dotnet_diagnostic.CA2301.severity = error # Do not call BinaryFormatter.Deserialize without first setting BinaryFormatter.Binder
220221
dotnet_diagnostic.CA2302.severity = error # Ensure BinaryFormatter.Binder is set before calling BinaryFormatter.Deserialize

src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ void StrongNameAssembly (AssemblyNameDefinition name)
353353
{
354354
using (Stream stream = typeof (GenerateResourceDesignerAssembly).Assembly.GetManifestResourceStream ("Resource.Designer.snk")) {
355355
byte[] publicKey = new byte[stream.Length];
356-
stream.Read (publicKey, 0, publicKey.Length);
356+
_ = stream.Read (publicKey, 0, publicKey.Length);
357357
name.HashAlgorithm = AssemblyHashAlgorithm.SHA1;
358358
name.PublicKey = SigningHelper.GetPublicKey (publicKey);
359359
name.HasPublicKey = true;

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,9 @@ public void MoveResource ()
158158
{
159159
var proj = new XamarinAndroidApplicationProject ();
160160
BuildItem image = null;
161-
using (var stream = typeof (XamarinAndroidCommonProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.Icon.png")) {
162-
var image_data = new byte [stream.Length];
163-
stream.Read (image_data, 0, (int)stream.Length);
164-
image = new AndroidItem.AndroidResource ("Resources\\drawable\\Image.png") { BinaryContent = () => image_data };
165-
proj.AndroidResources.Add (image);
166-
}
161+
var image_data = XamarinAndroidCommonProject.GetResourceContents ("Xamarin.ProjectTools.Resources.Base.Icon.png");
162+
image = new AndroidItem.AndroidResource ("Resources\\drawable\\Image.png") { BinaryContent = () => image_data };
163+
proj.AndroidResources.Add (image);
167164
using (var b = CreateApkBuilder ("temp/MoveResource")) {
168165
Assert.IsTrue (b.Build (proj), "First build should have succeeded.");
169166
var oldpath = image.Include ().Replace ('\\', Path.DirectorySeparatorChar);
@@ -213,14 +210,11 @@ public void RepetiviteBuildUpdateSingleResource ()
213210
var proj = new XamarinAndroidApplicationProject ();
214211
using (var b = CreateApkBuilder ()) {
215212
BuildItem image1, image2;
216-
using (var stream = typeof (XamarinAndroidCommonProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.Icon.png")) {
217-
var image_data = new byte [stream.Length];
218-
stream.Read (image_data, 0, (int)stream.Length);
219-
image1 = new AndroidItem.AndroidResource ("Resources\\drawable\\Image1.png") { BinaryContent = () => image_data };
220-
proj.AndroidResources.Add (image1);
221-
image2 = new AndroidItem.AndroidResource ("Resources\\drawable\\Image2.png") { BinaryContent = () => image_data };
222-
proj.AndroidResources.Add (image2);
223-
}
213+
var image_data = XamarinAndroidCommonProject.GetResourceContents ("Xamarin.ProjectTools.Resources.Base.Icon.png");
214+
image1 = new AndroidItem.AndroidResource ("Resources\\drawable\\Image1.png") { BinaryContent = () => image_data };
215+
proj.AndroidResources.Add (image1);
216+
image2 = new AndroidItem.AndroidResource ("Resources\\drawable\\Image2.png") { BinaryContent = () => image_data };
217+
proj.AndroidResources.Add (image2);
224218
b.ThrowOnBuildFailure = false;
225219
Assert.IsTrue (b.Build (proj), "First build was supposed to build without errors");
226220
var firstBuildTime = b.LastBuildTime;
@@ -251,21 +245,14 @@ public void Check9PatchFilesAreProcessed ()
251245
{
252246
var projectPath = Path.Combine ("temp", "Check9PatchFilesAreProcessed");
253247
var libproj = new XamarinAndroidLibraryProject () { ProjectName = "Library1"};
254-
using (var stream = typeof (XamarinAndroidCommonProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.Image.9.png")) {
255-
var image_data = new byte [stream.Length];
256-
stream.Read (image_data, 0, (int)stream.Length);
257-
var image2 = new AndroidItem.AndroidResource ("Resources\\drawable\\Image2.9.png") { BinaryContent = () => image_data };
258-
libproj.AndroidResources.Add (image2);
259-
}
248+
var image_data = XamarinAndroidCommonProject.GetResourceContents ("Xamarin.ProjectTools.Resources.Base.Image.9.png");
249+
var image2 = new AndroidItem.AndroidResource ("Resources\\drawable\\Image2.9.png") { BinaryContent = () => image_data };
250+
libproj.AndroidResources.Add (image2);
260251
using (var libb = CreateDllBuilder (Path.Combine (projectPath, "Library1"))) {
261252
libb.Build (libproj);
262253
var proj = new XamarinFormsMapsApplicationProject ();
263-
using (var stream = typeof (XamarinAndroidCommonProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.Image.9.png")) {
264-
var image_data = new byte [stream.Length];
265-
stream.Read (image_data, 0, (int)stream.Length);
266-
var image1 = new AndroidItem.AndroidResource ("Resources\\drawable\\Image1.9.png") { BinaryContent = () => image_data };
267-
proj.AndroidResources.Add (image1);
268-
}
254+
var image1 = new AndroidItem.AndroidResource ("Resources\\drawable\\Image1.9.png") { BinaryContent = () => image_data };
255+
proj.AndroidResources.Add (image1);
269256
proj.References.Add (new BuildItem ("ProjectReference", "..\\Library1\\Library1.csproj"));
270257
using (var b = CreateApkBuilder (Path.Combine (projectPath, "Application1"), false, false)) {
271258
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,7 @@ public void BuildBasicApplicationReleaseWithCustomAotProfile ()
8686
};
8787
proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidExtraAotOptions", "--verbose");
8888

89-
byte [] custom_aot_profile;
90-
using (var stream = typeof (XamarinAndroidApplicationProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.custom.aotprofile")) {
91-
custom_aot_profile = new byte [stream.Length];
92-
stream.Read (custom_aot_profile, 0, (int) stream.Length);
93-
}
89+
byte [] custom_aot_profile = XamarinAndroidCommonProject.GetResourceContents ("Xamarin.ProjectTools.Resources.Base.custom.aotprofile");
9490
proj.OtherBuildItems.Add (new BuildItem ("AndroidAotProfile", "custom.aotprofile") { BinaryContent = () => custom_aot_profile });
9591

9692
using var b = CreateApkBuilder ();

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,10 @@ public void BuildReleaseArm64 ([Values (false, true)] bool forms)
156156
proj.SetProperty ("LinkerDumpDependencies", "True");
157157
proj.SetProperty ("AndroidUseAssemblyStore", "False");
158158

159-
byte [] apkDescData;
160159
var flavor = (forms ? "XForms" : "Simple") + "DotNet";
161160
var apkDescFilename = $"BuildReleaseArm64{flavor}.apkdesc";
162161
var apkDescReference = "reference.apkdesc";
163-
using (var stream = typeof (XamarinAndroidApplicationProject).Assembly.GetManifestResourceStream ($"Xamarin.ProjectTools.Resources.Base.{apkDescFilename}")) {
164-
apkDescData = new byte [stream.Length];
165-
stream.Read (apkDescData, 0, (int) stream.Length);
166-
}
162+
byte [] apkDescData = XamarinAndroidCommonProject.GetResourceContents ($"Xamarin.ProjectTools.Resources.Base.{apkDescFilename}");
167163
proj.OtherBuildItems.Add (new BuildItem ("ApkDescFile", apkDescReference) { BinaryContent = () => apkDescData });
168164

169165
// use BuildHelper.CreateApkBuilder so that the test directory is not removed in tearup

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -720,11 +720,7 @@ public void ModifyManifest ([Values (true, false)] bool isRelease)
720720
[Test]
721721
public void MergeLibraryManifest ()
722722
{
723-
byte [] classesJar;
724-
using (var stream = typeof (XamarinAndroidCommonProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.classes.jar")) {
725-
classesJar = new byte [stream.Length];
726-
stream.Read (classesJar, 0, (int)stream.Length);
727-
}
723+
byte [] classesJar = XamarinAndroidCommonProject.GetResourceContents ("Xamarin.ProjectTools.Resources.Base.classes.jar");
728724
byte [] data;
729725
using (var ms = new MemoryStream ()) {
730726
using (var zip = ZipArchive.Create (ms)) {

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/GenerateResourceCaseMapTests.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,8 @@ public void CreateResourceDirectory (string path)
1616
Directory.CreateDirectory (Path.Combine (Root, path));
1717
Directory.CreateDirectory (Path.Combine (Root, path, "res", "drawable"));
1818
Directory.CreateDirectory (Path.Combine (Root, path, "res", "values"));
19-
using (var stream = typeof (XamarinAndroidCommonProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.Icon.png")) {
20-
var icon_binary_mdpi = new byte [stream.Length];
21-
stream.Read (icon_binary_mdpi, 0, (int)stream.Length);
22-
File.WriteAllBytes (Path.Combine (Root, path, "res", "drawable", "IMALLCAPS.png"), icon_binary_mdpi);
23-
}
19+
var icon_binary_mdpi = XamarinAndroidCommonProject.GetResourceContents ("Xamarin.ProjectTools.Resources.Base.Icon.png");
20+
File.WriteAllBytes (Path.Combine (Root, path, "res", "drawable", "IMALLCAPS.png"), icon_binary_mdpi);
2421
}
2522

2623
[Test]

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ManagedResourceParserTests.cs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,9 @@ public void CreateResourceDirectory (string path)
292292
File.WriteAllText (Path.Combine (Root, path, "lp", "res", "font", "arial.ttf"), "");
293293
File.WriteAllText (Path.Combine (Root, path, "lp", "res", "values", "strings.xml"), StringsXml2);
294294
File.WriteAllText (Path.Combine (Root, path, "lp", "res", "values", "dimen.xml"), Dimen);
295-
using (var stream = typeof (XamarinAndroidCommonProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.Icon.png")) {
296-
var icon_binary_mdpi = new byte [stream.Length];
297-
stream.Read (icon_binary_mdpi, 0, (int)stream.Length);
298-
File.WriteAllBytes (Path.Combine (Root, path, "lp", "res", "drawable", "ic_menu_preferences.png"), icon_binary_mdpi);
299-
File.WriteAllBytes (Path.Combine (Root, path, "lp", "res", "mipmap-hdpi", "icon.png"), icon_binary_mdpi);
300-
}
295+
var icon_binary_mdpi = XamarinAndroidCommonProject.GetResourceContents ("Xamarin.ProjectTools.Resources.Base.Icon.png");
296+
File.WriteAllBytes (Path.Combine (Root, path, "lp", "res", "drawable", "ic_menu_preferences.png"), icon_binary_mdpi);
297+
File.WriteAllBytes (Path.Combine (Root, path, "lp", "res", "mipmap-hdpi", "icon.png"), icon_binary_mdpi);
301298
File.WriteAllText (Path.Combine (Root, path, "lp", "res", "menu", "options.xml"), Menu);
302299
File.WriteAllText (Path.Combine (Root, path, "lp", "__res_name_case_map.txt"), "menu/Options.xml;menu/options.xml");
303300
}
@@ -318,13 +315,9 @@ void BuildLibraryWithResources (string path)
318315
library.AndroidResources.Add (new AndroidItem.AndroidResource (Path.Combine ("Resources", "values", "strings2.xml")) { TextContent = () => StringsXml2 });
319316
library.AndroidResources.Add (new AndroidItem.AndroidResource (Path.Combine ("Resources", "values", "dimen.xml")) { TextContent = () => Dimen });
320317

321-
using (var stream = typeof (XamarinAndroidCommonProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.Icon.png")) {
322-
var icon_binary_mdpi = new byte [stream.Length];
323-
stream.Read (icon_binary_mdpi, 0, (int)stream.Length);
324-
library.AndroidResources.Add (new AndroidItem.AndroidResource (Path.Combine ("Resources", "drawable", "ic_menu_preferences.png")) { BinaryContent = () => icon_binary_mdpi });
325-
library.AndroidResources.Add (new AndroidItem.AndroidResource (Path.Combine ("Resources", "mipmap-hdpi", "icon.png")) { BinaryContent = () => icon_binary_mdpi });
326-
}
327-
318+
var icon_binary_mdpi = XamarinAndroidCommonProject.GetResourceContents ("Xamarin.ProjectTools.Resources.Base.Icon.png");
319+
library.AndroidResources.Add (new AndroidItem.AndroidResource (Path.Combine ("Resources", "drawable", "ic_menu_preferences.png")) { BinaryContent = () => icon_binary_mdpi });
320+
library.AndroidResources.Add (new AndroidItem.AndroidResource (Path.Combine ("Resources", "mipmap-hdpi", "icon.png")) { BinaryContent = () => icon_binary_mdpi });
328321
library.AndroidResources.Add (new AndroidItem.AndroidResource (Path.Combine ("Resources", "menu", "options.xml")) { TextContent = () => Menu });
329322

330323
using (ProjectBuilder builder = CreateDllBuilder (Path.Combine (Root, path))) {

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/ResourceData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public static byte [] GetKeystore (string keyname = "test.keystore")
5757
var assembly = typeof (XamarinAndroidCommonProject).Assembly;
5858
using (var stream = assembly.GetManifestResourceStream ($"Xamarin.ProjectTools.Resources.Base.{keyname}")) {
5959
var data = new byte [stream.Length];
60-
stream.Read (data, 0, (int) stream.Length);
60+
_ = stream.Read (data, 0, (int) stream.Length);
6161
return data;
6262
}
6363
}

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidCommonProject.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static XamarinAndroidCommonProject ()
2626
icon_binary_xxxhdpi = GetResourceContents ("mipmap-xxxhdpi/appicon.png");
2727
}
2828

29-
static byte[] GetResourceContents (string resourceName)
29+
public static byte[] GetResourceContents (string resourceName)
3030
{
3131
var assembly = typeof (XamarinAndroidCommonProject).Assembly;
3232
var stream = assembly.GetManifestResourceStream (resourceName) ??
@@ -36,7 +36,7 @@ static byte[] GetResourceContents (string resourceName)
3636
}
3737
using (stream) {
3838
var contents = new byte [stream.Length];
39-
stream.Read (contents, 0, (int) stream.Length);
39+
_ = stream.Read (contents, 0, (int) stream.Length);
4040
return contents;
4141
}
4242
}

0 commit comments

Comments
 (0)