Halo semuanya. Hari ini kami memiliki proyek Microsoft lainnya. Dengan judul artikel ini, Anda bisa menebak bahwa kali ini pengembang tidak "tolong" kami dengan sejumlah besar kesalahan. Kami berharap penulis proyek tidak tersinggung dengan judulnya. Bagaimanapun, sejumlah kecil kesalahan itu bagus, bukan? Namun, kami masih berhasil menemukan sesuatu yang menarik dalam kode Azure PowerShell. Kami menyarankan Anda untuk mengetahui fitur-fitur proyek ini dan memeriksa kesalahan, yang ditemukan menggunakan penganalisis # PVS-Studio C.
Tentang proyek
Azure PowerShell adalah sekumpulan commandlets (
cmdlet ) yang memungkinkan Anda mengelola sumber daya
Azure langsung dari baris perintah
PowerShell . Tujuan utama dari rangkaian ini adalah untuk menyederhanakan proses belajar dan dengan cepat memulai pengembangan untuk Azure. Azure PowerShell memberi administrator dan pengembang fitur menarik untuk membuat, menyebarkan, dan mengelola aplikasi Microsoft Azure.
Azure PowerShell dikembangkan di lingkungan .NET Standard, didukung oleh PowerShell 5.1 untuk Windows dan PowerShell 6.x dan yang lebih baru untuk semua platform.
Kode sumber Azure PowerShell tersedia di GitHub.
Baru-baru ini saya sering mendapatkan proyek Microsoft untuk diperiksa. Menurut pendapat saya, kualitas proyek-proyek ini biasanya terkemuka. Meskipun, tentu saja, bukan tanpa pengecualian, seperti yang dijelaskan dalam artikel "
WinForms: Errors, Holmes ". Tapi kali ini semuanya baik-baik saja. Proyek ini besar: 6845 file kode sumber .cs berisi sekitar 700.000 baris, tidak termasuk baris kosong (saya tidak memperhitungkan tes akun dan peringatan tingkat kepastian ketiga). Sangat sedikit kesalahan ditemukan untuk jumlah kode seperti itu: tidak lebih dari seratus. Ada banyak kasus serupa, jadi saya memilih yang paling menarik untuk artikel ini. Seperti biasa, saya mengurutkan kesalahan berdasarkan nomor peringatan PVS-Studio.
Saya juga menemukan beberapa fragmen kode yang terlihat seperti kesalahan, tetapi tidak bisa dikenali sebagai kesalahan, karena saya tidak cukup akrab dengan kekhasan pengembangan PowerShell. Saya berharap bahwa di antara pembaca akan ada spesialis dalam masalah ini yang akan membantu saya. Saya akan jelaskan secara rinci di bawah ini.
Sebelum bagian umpan balik, saya ingin menyebutkan struktur spesifik proyek. Kode sumber Azure PowerShell terdiri dari lebih dari tujuh puluh solusi Visual Studio. Beberapa solusi termasuk proyek dari yang lain. Struktur ini sedikit memperlambat analisis (tidak banyak). Tetap saja cek itu tidak menyebabkan kesulitan lain. Untuk kenyamanan, dalam pesan kesalahan (dalam tanda kurung) Saya akan menentukan nama solusi tempat kesalahan ditemukan.
Hasil analisis
V3001 Ada sub-ekspresi identik 'strTimespan.Berisi ("M")' di sebelah kiri dan di sebelah kanan dari '||' operator. AzureServiceBusCmdletBase.cs 187 (EventGrid)
public static TimeSpan ParseTimespan(string strTimespan) { .... if (strTimespan.Contains("P") || strTimespan.Contains("D") || strTimespan.Contains("T") || strTimespan.Contains("H") || strTimespan.Contains("M") || strTimespan.Contains("M")) .... }
Contoh kesalahan yang cukup jelas yang hanya dapat diperbaiki oleh pengembang. Dalam kasus ini, sama sekali tidak jelas apakah kita berurusan dengan duplikasi kode yang tidak memengaruhi apa pun atau sesuatu yang harus dilakukan alih-alih
"M" di salah satu dari dua pemeriksaan terakhir.
V3001 Ada sub-ekspresi identik 'this.AggregationType! = Null' di kiri dan di kanan operator '&&'. GetAzureRmMetricCommand.cs 156 (Monitor)
public AggregationType? AggregationType { get; set; } .... protected override void ProcessRecordInternal() { .... string aggregation = (this.AggregationType != null && this.AggregationType.HasValue) ? this.AggregationType.Value.ToString() : null; .... }
Mungkin tidak ada kesalahan di sini. Ini adalah contoh kode redundan. Terkadang kode seperti itu menunjukkan kurangnya pengetahuan pengembang. Intinya adalah bahwa cek
this.AggregationType! = Null dan
this.AggregationType.HasValue identik. Cukup menggunakan satu saja (salah satunya). Secara pribadi, saya lebih suka opsi dengan
HasValue: string aggregation = this.AggregationType.HasValue ? this.AggregationType.Value.ToString() : null;
V3003 Penggunaan
pola 'jika (A) {...} else jika (A) {...}' terdeteksi. Ada kemungkinan kehadiran kesalahan logis. Periksa baris: 152, 163. GetAzureRmRecoveryServicesBackupProtectionPolicy.cs 152 (RecoveryServices)
public override void ExecuteCmdlet() { .... if( WorkloadType == Models.WorkloadType.AzureVM ) { .... } .... else if( WorkloadType == Models.WorkloadType.AzureFiles ) { if( BackupManagementType != Models.BackupManagementType.AzureStorage ) { throw new ArgumentException( Resources.AzureFileUnsupportedBackupManagementTypeException ); } serviceClientProviderType = ServiceClientHelpers. GetServiceClientProviderType( Models.WorkloadType.AzureFiles ); } else if( WorkloadType == Models.WorkloadType.AzureFiles ) { if( BackupManagementType != Models.BackupManagementType.AzureStorage ) { throw new ArgumentException( Resources.AzureFileUnsupportedBackupManagementTypeException ); } serviceClientProviderType = ServiceClientHelpers. GetServiceClientProviderType( Models.WorkloadType.AzureFiles ); } .... }
Dua
lagi jika balok benar-benar identik, termasuk kondisi dan badan balok. Kesalahan seperti itu biasanya dibuat ketika menggunakan metode salin-tempel. Masalahnya di sini adalah lagi kekritisan kesalahan itu. Jika ini bukan duplikasi kode yang sederhana, ini mungkin merupakan pemeriksaan yang tidak diperlukan dan serangkaian tindakan yang sesuai. Penulis pasti harus mengedit kode.
V3005 Variabel 'this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent' ditugaskan untuk dirinya sendiri. SetAzureVMOperatingSystemCommand.cs 298 (Hitung)
public override void ExecuteCmdlet() { ....
Nilai properti ditentukan sendiri. Lihatlah deklarasi ini:
[JsonProperty(PropertyName = "provisionVMAgent")] public bool? ProvisionVMAgent { get; set; }
Deskripsi
JsonProperty menyatakan: "Menginstruksikan Newtonsoft.Json.JsonSerializer untuk selalu membuat serial anggota dengan nama yang ditentukan." Tampaknya semuanya tidak bersalah dan kesalahan yang jelas telah dibuat. Penggunaan eksplisit
ini untuk mengakses properti juga cukup membingungkan. Mungkin, variabel lain tidak ditentukan secara salah alih-alih
ini. Tapi jangan langsung menyimpulkan. Faktanya adalah bahwa saya menemukan cukup banyak penugasan semacam itu (sebuah properti ditugaskan sendiri). Berikut adalah contoh tugas, sangat mirip dengan kesalahan:
V3005 Variabel 'this.LastHeartbeat' ditugaskan untuk dirinya sendiri. PSFabricDetails.cs 804 (RecoveryServices)
public ASRInMageAzureV2SpecificRPIDetails( InMageAzureV2ReplicationDetails details) { this.LastHeartbeat = this.LastHeartbeat;
Mari kita lihat lebih dekat tugas kedua dan selanjutnya. Di bagian kanan ungkapan,
detail terjadi alih-alih
ini. Sekarang lihat deklarasi properti
this.LastHeartbeat terakhir :
public DateTime? LastHeartbeat { get; set; }
Akhirnya, mari kita cari properti dengan nama yang sama di kelas
InMageAzureV2ReplicationDetails . Properti seperti itu dinyatakan di sana:
public class InMageAzureV2ReplicationDetails : ReplicationProviderSpecificSettings { .... [JsonProperty(PropertyName = "lastHeartbeat")] public DateTime? LastHeartbeat { get; set; } .... }
Nah, dalam hal ini, saya mau mengakui itu adalah kesalahan nyata. Tapi apa yang harus kita lakukan dengan peringatan selanjutnya? Tidak seperti dua fragmen kode sebelumnya, ada beberapa properti yang ditugaskan sendiri. Yah, ini kelihatannya kurang seperti kesalahan:
- V3005 Variabel 'this.ResourceGroupName' ditugaskan untuk dirinya sendiri. RemoveAzureRmExpressRouteConnectionCommand.cs 84 (CognitiveServices)
- V3005 Variabel 'this.ExpressRouteGatewayName' ditugaskan untuk dirinya sendiri. RemoveAzureRmExpressRouteConnectionCommand.cs 85 (CognitiveServices)
- V3005 Variabel 'this.Name' ditugaskan untuk dirinya sendiri. RemoveAzureRmExpressRouteConnectionCommand.cs 86 (CognitiveServices)
[Cmdlet(VerbsCommon.Remove, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ExpressRouteConnection", DefaultParameterSetName = CortexParameterSetNames.ByExpressRouteConnectionName, SupportsShouldProcess = true), OutputType(typeof(bool))] public class RemoveExpressRouteConnectionCommand : ExpressRouteConnectionBaseCmdlet { [Parameter( Mandatory = true, ParameterSetName = CortexParameterSetNames.ByExpressRouteConnectionName, HelpMessage = "The resource group name.")] [ResourceGroupCompleter] [ValidateNotNullOrEmpty] public string ResourceGroupName { get; set; } .... public override void Execute() { if (....) { this.ResourceGroupName = this.ResourceGroupName; this.ExpressRouteGatewayName = this.ExpressRouteGatewayName; this.Name = this.Name; } .... } .... }
Metode
Execute berisi penetapan-sendiri tiga properti secara berurutan. Untuk berjaga-jaga, saya mengutip deklarasi penuh kelas
RemoveExpressRouteConnectionCommand dan semua atributnya, serta deklarasi properti
ResourceGroupName (dua properti lainnya dinyatakan dengan cara yang sama). Peringatan-peringatan inilah yang membuat saya berpikir tentang pertanyaan: "Apakah ini kesalahan?" Saya menduga bahwa beberapa keajaiban internal pengembangan PowerShell mungkin terjadi di sini. Saya berharap di antara pembaca akan ada ahli yang diberitahu tentang masalah ini. Saya belum siap untuk menarik kesimpulan apa pun dalam kasus ini.
V3006 Objek telah dibuat tetapi tidak sedang digunakan. Kata kunci 'lempar' bisa hilang: lempar ArgumentException baru (FOO). StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 259 (RecoveryServices)
private void StartRPITestFailover() { .... if (....) { .... } else { new ArgumentException( Resources .UnsupportedDirectionForTFO);
Kata kunci
lemparan dihilangkan. Dan komentar itu mengatakan bahwa pengecualian itu harus dibuang. Saya menemukan beberapa kesalahan serupa dalam solusi
RecoveryServices :
- V3006 Objek telah dibuat tetapi tidak sedang digunakan. Kata kunci 'lempar' bisa hilang: lempar ArgumentException baru (FOO). StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 305 (RecoveryServices)
- V3006 Objek telah dibuat tetapi tidak sedang digunakan. Kata kunci 'lempar' bisa hilang: lempar ArgumentException baru (FOO). StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 278 (RecoveryServices)
- V3006 Objek telah dibuat tetapi tidak sedang digunakan. Kata kunci 'lempar' bisa hilang: lempar ArgumentException baru (FOO). StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 322 (RecoveryServices)
- V3006 Objek telah dibuat tetapi tidak sedang digunakan. Kata kunci 'lempar' bisa hilang: lempar ArgumentException baru (FOO). PerbaruiAzureRmRecoveryServicesAsrProtectionDirection.cs 421 (RecoveryServices)
- V3006 Objek telah dibuat tetapi tidak sedang digunakan. Kata kunci 'lempar' bisa hilang: lempar ArgumentException baru (FOO). PerbaruiAzureRmRecoveryServicesAsrProtectionDirection.cs 452 (RecoveryServices)
Ekspresi
V3022 'apiType.HasValue' selalu salah. ApiManagementClient.cs 1134 (ApiManagement)
private string GetApiTypeForImport(...., PsApiManagementApiType? apiType) { .... if (apiType.HasValue) { switch(apiType.Value) { case PsApiManagementApiType.Http: return SoapApiType.SoapToRest; case PsApiManagementApiType.Soap: return SoapApiType.SoapPassThrough; default: return SoapApiType.SoapPassThrough; } } return apiType.HasValue ?
Logika pekerjaan telah rusak. Jika
apiType berisi nilai, kontrol tidak akan mencapai ekspresi
kembali di akhir metode (semua cabang
switch berisi
pengembalian ). Jika tidak, metode ini akan selalu mengembalikan
PsApiManagementApiType.Http.ToString ("g") , sedangkan nilai
apiType.Value.ToString ("g") tidak akan pernah dikembalikan.
Ekspresi
V3022 'automationJob! = Null && automationJob == null' selalu salah. NodeConfigurationDeployment.cs 199 (Automation)
public NodeConfigurationDeployment( ...., Management.Automation.Models.Job automationJob = null, ....) { .... if (automationJob != null && automationJob == null) return; .... }
Kode kontra-intuitif. Dua cek yang saling bertentangan. Mungkin cek kedua untuk
null berisi variabel yang salah.
Ekspresi
V3022 selalu salah. DataFactoryClient.Encrypt.cs 37 (DataFactory)
public virtual string OnPremisesEncryptString(....) { .... if ( linkedServiceType == LinkedServiceType.OnPremisesSqlLinkedService && linkedServiceType == LinkedServiceType.OnPremisesOracleLinkedService && linkedServiceType == LinkedServiceType.OnPremisesFileSystemLinkedService && (value == null || value.Length == 0)) { throw new ArgumentNullException("value"); } .... }
Cek tidak ada gunanya dan pengecualian tidak akan pernah dilempar. Kondisi ini membutuhkan
persamaan variabel dengan variabel
linkedServiceType untuk tiga nilai yang berbeda. Operator && dan || cenderung bingung. Kode tetap:
if (( linkedServiceType == LinkedServiceType.OnPremisesSqlLinkedService || linkedServiceType == LinkedServiceType.OnPremisesOracleLinkedService || linkedServiceType == LinkedServiceType.OnPremisesFileSystemLinkedService) && (value == null || value.Length == 0)) ....
Ekspresi
V3022 'Ekus == null' selalu salah. PSKeyVaultCertificatePolicy.cs 129 (KeyVault)
internal CertificatePolicy ToCertificatePolicy() { .... if (Ekus != null) { x509CertificateProperties.Ekus = Ekus == null ? null : new List<string>(Ekus); } .... }
Cek
berlebihan variabel
Ekus untuk
null . Mungkin baik-baik saja, tetapi kodenya tidak terlihat bagus.
V3023 Pertimbangkan untuk memeriksa ungkapan ini. Ekspresi berlebihan atau mengandung kesalahan cetak. PolicyRetentionObjects.cs 207 (RecoveryServices)
public virtual void Validate() { if (RetentionTimes == null || RetentionTimes.Count == 0 || RetentionTimes.Count != 1) { throw new ArgumentException( Resources.InvalidRetentionTimesInPolicyException); } }
Berikut ini pemeriksaan berlebihan atau kondisi berlebihan. Pemeriksaan
RetentionTimes.Count == 0 tidak ada gunanya, karena setelah itu, centang
RetentionTimes.Count! = 1 mengikuti.
V3025 Format salah. Jumlah item format yang berbeda diharapkan saat memanggil fungsi 'Format'. Argumen tidak digunakan: this.ResourceGroupName. NewScheduledQueryRuleCommand.cs 117 (Monitor)
protected override void ProcessRecordInternal() { .... if (this.ShouldProcess(this.Name, string.Format("Creating Log Alert Rule '{0}' in resource group {0}", this.Name, this.ResourceGroupName))) { .... } .... }
Kesalahan pada baris pemformatan. Penentu
{0} digunakan dua kali, dan metode
Format dilewatkan dua argumen. Ini versi yang benar:
if (this.ShouldProcess(this.Name, string.Format("Creating Log Alert Rule '{0}' in resource group {1}", this.Name, this.ResourceGroupName))) ....
Kesalahan serupa lainnya:
- V3025 Format salah. Jumlah item format yang berbeda diharapkan saat memanggil fungsi 'Format'. Argumen tidak digunakan: this.ResourceGroupName. RemoveScheduledQueryRuleCommand.cs 88 (Monitor)
V3042 Kemungkinan NullReferenceException. '?.' dan '.' operator digunakan untuk mengakses anggota objek 'imageAndOsType' VirtualMachineScaleSetStrategy.cs 81 (Hitung)
internal static ResourceConfig<VirtualMachineScaleSet> CreateVirtualMachineScaleSetConfig(...., ImageAndOsType imageAndOsType, ....) { .... VirtualMachineProfile = new VirtualMachineScaleSetVMProfile { OsProfile = new VirtualMachineScaleSetOSProfile { ...., WindowsConfiguration = imageAndOsType.CreateWindowsConfiguration(),
Saat membuat objek
VirtualMachineScaleSetVMPile , variabel
imageAndOsType diperiksa untuk
nol tanpa pemeriksaan pendahuluan. Namun, lebih lanjut ketika membuat
VirtualMachineScaleSetStorageProfile , variabel ini sudah diperiksa menggunakan operator akses bersyarat bahkan dua kali. Kode tidak terlihat aman.
V3042 Kemungkinan NullReferenceException. '?.' dan '.' operator digunakan untuk mengakses anggota objek 'existingContacts' RemoveAzureKeyVaultCertificateContact.cs 123 (KeyVault)
public override void ExecuteCmdlet() { .... List<PSKeyVaultCertificateContact> existingContacts; try { existingContacts = this.DataServiceClient. GetCertificateContacts(VaultName)?.ToList(); } catch (KeyVaultErrorException exception) { .... existingContacts = null; } foreach (var email in EmailAddress) { existingContacts.RemoveAll(....);
Baik dalam eksekusi normal dan sebagai hasil dari penanganan pengecualian, variabel yang
adaContacts bisa mendapatkan nilai
nol , setelah itu eksekusi akan berlanjut. Lebih lanjut dalam kode, variabel ini digunakan tanpa alasan khusus.
V3066 Kemungkinan urutan argumen yang salah diteruskan ke metode 'PersistSyncServerRegistration': 'storageSyncServiceUid' dan 'discoveryUri'. EcsManagementInteropClient.cs 364 (StorageSync)
public class EcsManagementInteropClient : IEcsManagement { .... public int PersistSyncServerRegistration(....) { return m_managementObject.PersistSyncServerRegistration( serviceUri, subscriptionId, storageSyncServiceName, resourceGroupName, clusterId, clusterName, storageSyncServiceUid,
Penganalisa menduga bahwa urutan argumen dari metode
PersistSyncServerRegistration bingung. Deklarasi metode:
public interface IEcsManagement : IDisposable { .... int PersistSyncServerRegistration( [In, MarshalAs(UnmanagedType.BStr)] string serviceUri, [In, MarshalAs(UnmanagedType.BStr)] string subscriptionId, [In, MarshalAs(UnmanagedType.BStr)] string storageSyncServiceName, [In, MarshalAs(UnmanagedType.BStr)] string resourceGroupName, [In, MarshalAs(UnmanagedType.BStr)] string clusterId, [In, MarshalAs(UnmanagedType.BStr)] string clusterName, [In, MarshalAs(UnmanagedType.BStr)] string discoveryUri,
Memang, ada yang salah di sini dengan argumen nomor tujuh dan delapan. Penulis harus memeriksa kodenya.
V3077 Setter properti 'GetGuid' tidak menggunakan parameter 'nilai'. RecoveryServicesBackupCmdletBase.cs 54 (RecoveryServices)
public abstract class RecoveryServicesBackupCmdletBase : AzureRMCmdlet { .... static string _guid; protected static string GetGuid { get { return _guid; } set { _guid = Guid.NewGuid().ToString(); } } .... }
Setter tidak menggunakan parameter yang diteruskan. Alih-alih, itu membuat GUID baru dan menugaskannya ke bidang
_guid . Saya pikir sebagian besar pembaca akan setuju bahwa kode tersebut terlihat paling jelek. Konstruksi ini sangat tidak nyaman untuk digunakan: ketika (kembali) menginisialisasi properti
GetGuid , seseorang harus memberikannya nilai palsu, yang tidak terlalu jelas. Tetapi yang terpenting saya terhibur dengan cara penulis menggunakan pola ini. Hanya ada satu tempat, di mana
GetGuid ditangani. Lihat ini:
public override void ExecuteCmdlet() { .... var itemResponse = ServiceClientAdapter.CreateOrUpdateProtectionIntent( GetGuid ?? Guid.NewGuid().ToString(), ....); .... }
Cemerlang!
V3091 Analisis empiris. Mungkin salah ketik ada di dalam string literal: "Id Grup Manajemen." Kata 'Id' mencurigakan. Constants.cs 36 (Sumber)
public class HelpMessages { public const string SubscriptionId = "Subscription Id of the subscription associated with the management"; public const string GroupId = "Management Group Id";
Penganalisis menunjuk ke kemungkinan kesalahan dalam string yang ditetapkan untuk konstanta
GroupName . Kesimpulannya didasarkan pada analisis empiris penugasan lain, dengan mempertimbangkan nama-nama variabel. Saya pikir dalam hal ini analisanya benar, dan nilai konstanta
GroupName harus menjadi semacam "Nama Grup Manajemen". Mungkin kesalahan terjadi karena fakta bahwa nilai untuk konstanta
GroupId disalin, tetapi tidak berubah.
Kesalahan serupa lainnya:
- V3091 Analisis empiris. Mungkin salah ketik ada di dalam string literal. Kata 'Nama' mencurigakan. ParamHelpMsgs.cs 153 (RecoveryServices)
V3093 The '|' operator mengevaluasi kedua operan. Mungkin hubungan arus pendek '||' Operator harus digunakan sebagai gantinya. PSKeyVaultCertificatePolicy.cs 114 (KeyVault)
internal CertificatePolicy ToCertificatePolicy() { .... if (!string.IsNullOrWhiteSpace(SubjectName) || DnsNames != null || Ekus != null || KeyUsage != null |
Dalam fragmen ini kesalahan mungkin terjadi dan di blok
if antara dua kondisi terakhir || Operator mungkin telah digunakan. Namun seperti yang sering terjadi, hanya pengembang yang bisa memberikan jawaban yang tepat.
V3095 Objek 'sertifikat' digunakan sebelum diverifikasi terhadap nol. Periksa baris: 41, 43. CertificateInfo.cs 41 (Automation)
public CertificateInfo( ...., Azure.Management.Automation.Models.Certificate certificate) { .... this.Name = certificate.Name; if (certificate == null) return; .... }
Klasik Pertama objek digunakan dan hanya setelah itu referensi diperiksa
nol . Kami menemukan kesalahan seperti itu
sangat sering . Mari kita pertimbangkan kesalahan serupa lainnya.
V3095 Objek 'clusterCred' digunakan sebelum diverifikasi terhadap nol. Periksa baris: 115, 118. InvokeHiveCommand.cs 115 (HDInsight)
public override void ExecuteCmdlet() { .... _credential = new BasicAuthenticationCloudCredentials { Username = clusterCred.UserName, Password = clusterCred.Password.ConvertToString() }; if (clusterConnection == null || clusterCred == null) .... }
Berikut beberapa kesalahan serupa:
- V3095 Objek '_profile' digunakan sebelum diverifikasi terhadap null. Periksa baris: 47, 49. RMProfileClient.cs 47 (Akun)
- V3095 Objek 'this.LoadBalancer.BackendAddressPools' digunakan sebelum diverifikasi terhadap nol. Periksa baris: 56, 63. AddAzureRmLoadBalancerBackendAddressPoolConfigCommand.cs 56 (CognitiveServices)
- Secara umum, saya melihat banyak kesalahan V3095 dalam kode Azure PowerShell. Tetapi semuanya sangat mirip, jadi saya tidak akan membahas masalah ini.
V3125 Objek 'startTime' digunakan setelah diverifikasi terhadap nol. Periksa baris: 1752, 1738. AutomationPSClientDSC.cs 1752 (Automation)
private string GetNodeReportListFilterString( ...., DateTimeOffset? startTime, ...., DateTimeOffset? lastModifiedTime) { .... if (startTime.HasValue) { odataFilter.Add("properties/startTime ge " + this.FormatDateTime(startTime.Value));
Ini juga merupakan jenis kesalahan yang tersebar luas. Variabel
startTime diperiksa untuk keberadaan nilai saat pertama kali digunakan. Tapi itu tidak dilakukan pada penggunaan selanjutnya. Nah, situasinya bisa lebih buruk. Lihatlah blok
if yang kedua. Saya pikir variabel
startTime tidak boleh ada di sini sama sekali. Pertama, tidak ada pemeriksaan untuk keberadaan nilai sebelum penggunaannya. Kedua, string yang dibentuk untuk diteruskan ke metode
Add juga mengkonfirmasi saran saya. Variabel lain
(lastModifiedTime ) disebutkan di bagian pertama dari string ini.
V3125 Objek 'firstPage' digunakan setelah diverifikasi terhadap null. Periksa baris: 113, 108. IntegrationAccountAgreementOperations.cs 113 (LogicApp)
public IList<IntegrationAccountAgreement> ListIntegrationAccountAgreements(....) { var compositeList = new List<IntegrationAccountAgreement>(); var firstPage = this.LogicManagementClient. IntegrationAccountAgreements.List(....); if (firstPage != null) { compositeList.AddRange(firstPage); } if (!string.IsNullOrEmpty(firstPage.NextPageLink))
Kesalahan jelas lainnya. Variabel
firstPage tidak aman digunakan terlepas dari kenyataan bahwa sebelumnya dalam kode variabel ini sudah digunakan sedang diperiksa awal untuk
null .
Saya bahkan menemukan lebih banyak peringatan
V3125 dalam kode Azure PowerShell daripada yang dijelaskan di atas. Semuanya juga dari tipe yang sama. Saya pikir, dua dari mereka yang kami pertimbangkan sudah cukup.
V3137 Variabel 'apiVersionSetId' ditugaskan tetapi tidak digunakan pada akhir fungsi. GetAzureApiManagementApiVersionSet.cs 69 (ApiManagement)
public String ApiVersionSetId { get; set; } .... public override void ExecuteApiManagementCmdlet() { .... string apiVersionSetId; if (ParameterSetName.Equals(ContextParameterSet)) { .... apiVersionSetId = ApiVersionSetId; } else { apiVersionSetId = ....; } if (string.IsNullOrEmpty(ApiVersionSetId))
Penganalisa melaporkan bahwa variabel lokal
apiVersionSetId diinisialisasi, tetapi tidak digunakan dengan cara apa pun. Seringkali pola ini menunjukkan kesalahan. Saya pikir, dalam kasus ini kemungkinan besar kesalahan, terutama dengan mempertimbangkan fakta bahwa nama variabel lokal
apiVersionSetId dan nama properti
ApiVersionSetId hanya berbeda dengan huruf pertama. Lihatlah kodenya. Setelah menginisialisasi
properti apiVersionSetId (dengan satu atau lain cara), hanya properti
ApiVersionSetId yang digunakan lebih lanjut dalam kode. Ini terlihat sangat mencurigakan.
V3137 Variabel 'cacheId' ditugaskan tetapi tidak digunakan pada akhir fungsi. RemoveAzureApiManagementCache.cs 94 (ApiManagement)
public String CacheId { get; set; } .... public override void ExecuteApiManagementCmdlet() { .... string cacheId; if (....) { .... cacheId = InputObject.CacheId; } else if (....) { .... cacheId = cache.CacheId; } else { .... cacheId = CacheId; } var actionDescription = string.Format(...., CacheId);
Ini adalah kasus yang hampir sama dengan yang dijelaskan sebelumnya.
Variabel lokal
cacheId tidak digunakan setelah inisialisasi dengan cara apa pun. Sebaliknya, properti lain dengan nama yang sangat mirip
CacheId digunakan. Saya tidak tahu pasti, mungkin itu hanya pola pemrograman pengembang Azure PowerShell. Bagaimanapun, sepertinya ada kesalahan.
V3143 Parameter 'nilai' ditulis ulang di dalam setter properti, dan tidak digunakan setelah itu. NewAzureIntegrationAccountPartnerCommand.cs 67 (LogicApp)
[Parameter(Mandatory = false, HelpMessage = "The integration account partner type.", ValueFromPipelineByPropertyName = false)] [ValidateSet("B2B", IgnoreCase = false)] [ValidateNotNullOrEmpty] public string PartnerType { get { return this.partnerType; } set { value = this.partnerType; }
Bidang
partnerType dideklarasikan dengan cara berikut:
Meskipun nama solusi (LogicApp) tempat kesalahan terdeteksi, saya tidak menemukan logika di dalamnya. Mengubah
nilai dalam setter bukanlah kejadian langka, tetapi dalam kasus ini berkaitan dengan hilangnya nilai asli. Terlihat aneh. Dalam kode properti dibaca hanya sekali. Mungkin, kita perlu meminta nasihat ahli lagi. Mungkin saya tidak mengerti. Intinya adalah saya menemukan beberapa pola yang sama:
- V3143 Parameter 'nilai' ditulis ulang di dalam setter properti, dan tidak digunakan setelah itu. NewAzureIntegrationAccountSchemaCommand.cs 79 (LogicApp)
- V3143 Parameter 'nilai' ditulis ulang di dalam setter properti, dan tidak digunakan setelah itu. NewAzureIntegrationAccountSchemaCommand.cs 87 (LogicApp)
- V3143 Parameter 'nilai' ditulis ulang di dalam setter properti, dan tidak digunakan setelah itu. UpdateAzureIntegrationAccountPartnerCommand.cs 67 (LogicApp)
- V3143 Parameter 'nilai' ditulis ulang di dalam setter properti, dan tidak digunakan setelah itu. PerbaruiAzureIntegrationAccountSchemaCommand.cs 80 (LogicApp)
- V3143 Parameter 'nilai' ditulis ulang di dalam setter properti, dan tidak digunakan setelah itu. PerbaruiAzureIntegrationAccountSchemaCommand.cs 88 (LogicApp)
Kesimpulan
Ini semua bug menarik yang ditemukan dalam kode Azure PowerShell. Penggemar dan mereka yang tertarik dipersilakan untuk meninjau kesalahan sendiri dalam proyek ini (atau lainnya). Saya mungkin bisa melewatkan sesuatu yang offbeat. Untuk melakukan review, Anda hanya perlu mengunduh dan menginstal
PVS-Studio .
Terima kasih sudah membaca sampai akhir. Dan, tentu saja, kode tanpa bug untuk semua orang!