Halo semuanya. Hari ini kami memiliki proyek Microsoft lain yang diuji. Dengan judul artikel, Anda dapat menebak bahwa kali ini para pengembang tidak dapat menyenangkan kami dengan sejumlah besar kesalahan. Kami berharap bahwa penulis proyek tidak akan tersinggung dengan namanya. Bagaimanapun, sejumlah kecil kesalahan sangat bagus, bukan? Namun, sesuatu yang menarik ditemukan dalam kode Azure PowerShell. Kami sarankan agar Anda membiasakan diri dengan fitur-fitur proyek ini dan melihat kesalahan yang ditemukan pada PV # C-analyzer PVS-Studio.
Tentang proyek
Azure PowerShell adalah cmdlet yang memungkinkan Anda untuk mengelola sumber daya
Azure langsung dari baris perintah
PowerShell . Tujuan utama set ini adalah untuk menyederhanakan pembelajaran dan mulai cepat pengembangan untuk Azure. Azure PowerShell memberi para administrator dan pengembang fitur-fitur canggih untuk membuat, menyebarkan, dan mengelola aplikasi Microsoft Azure.
Azure PowerShell dikembangkan di lingkungan .NET Standard dan didukung oleh PowerShell 5.1 untuk Windows dan PowerShell 6.x dan lebih tinggi untuk semua platform.
Kode sumber Azure PowerShell tersedia di GitHub.
Baru-baru ini, proyek Microsoft sering menarik perhatian saya. Menurut pendapat saya, kualitas proyek-proyek ini biasanya yang terbaik. Meskipun, tentu saja, bukan tanpa pengecualian, seperti artikel "
WinForms: errors, Holmes ". Namun, kali ini semuanya normal. Proyek ini besar: 6845 file .cs kode sumber berisi sekitar 700 ribu baris, tidak termasuk kosong (tes, serta peringatan tingkat ketiga keandalan, saya tidak memperhitungkan). Ada sangat sedikit kesalahan untuk volume kode seperti itu: tidak lebih dari seratus. Ada cukup banyak situasi dengan jenis yang sama, jadi untuk artikel yang saya pilih positif yang paling menarik. Kesalahan, seperti yang biasa saya lakukan, diurutkan berdasarkan nomor diagnostik PVS-Studio.
Saya juga menemukan fragmen kode yang terlihat seperti kesalahan, tetapi saya tidak bisa membuat kesimpulan yang jelas tentang keberadaan masalah nyata, karena saya tidak cukup akrab dengan fitur desain untuk PowerShell. Saya berharap di antara pembaca akan ada ahli dalam masalah ini dan akan membantu saya. Tentang itu di bawah ini.
Sebelum dimulainya "pembekalan," saya perhatikan fitur proyek dalam hal strukturnya. Kode sumber Azure PowerShell terdiri dari lebih dari tujuh puluh solusi Visual Studio. Beberapa solusi termasuk proyek dari solusi lain. Struktur seperti itu memperlambat analisis sedikit (tidak banyak). Sisa verifikasi tidak menimbulkan kesulitan. Untuk kenyamanan, di baris pesan kesalahan (dalam tanda kurung) saya akan menunjukkan nama solusi di mana kesalahan ini terdeteksi.
Hasil Validasi
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 hal ini, sama sekali tidak dapat dipahami apakah kita berurusan dengan duplikasi kode yang tidak mempengaruhi apa pun, atau bukannya
"M" sesuatu yang lain harus muncul dalam 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 mengindikasikan tingkat pengetahuan pengembang yang tidak memadai. Faktanya adalah bahwa
this.AggregationType! = Null dan
this.AggregationType.HasValue cek identik. Cukup menggunakan salah satunya (apa saja). Secara pribadi, saya lebih suka
opsi 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
lainnya jika balok benar-benar identik, termasuk kondisi dan tubuh balok. Kesalahan seperti itu biasanya dibuat ketika menggunakan metode salin-tempel dalam pekerjaan. Pertanyaannya lagi adalah kekritisan kesalahan ini. Jika ini bukan duplikasi kode yang sederhana, maka kita dapat berbicara tentang kurangnya verifikasi yang diperlukan dan serangkaian tindakan yang sesuai. Penulis perlu mengedit kode.
V3005 Variabel 'this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent' ditugaskan untuk dirinya sendiri. SetAzureVMOperatingSystemCommand.cs 298 (Hitung)
public override void ExecuteCmdlet() { ....
Nilai properti ditugaskan untuk dirinya sendiri. Lihatlah iklannya:
[JsonProperty(PropertyName = "provisionVMAgent")] public bool? ProvisionVMAgent { get; set; }
Deskripsi
JsonProperty mengatakan "Menginstruksikan Newtonsoft.Json.JsonSerializer untuk selalu membuat serial anggota dengan nama yang ditentukan". Tampaknya semuanya sederhana dan ada kesalahan yang jelas. Juga membingungkan adalah penggunaan eksplisit
ini untuk mengakses properti. Mungkin, secara tidak sengaja, beberapa variabel lain tidak ditentukan selain
ini . Tapi untuk saat ini, kami tidak akan menarik kesimpulan. Faktanya adalah bahwa dalam kode Azure PowerShell saya bertemu cukup banyak penugasan seperti itu (properti ditugaskan untuk dirinya sendiri). Berikut adalah contoh tugas yang sangat mirip dengan kesalahan:
V3005 Variabel 'this.LastHeartbeat' ditugaskan untuk dirinya sendiri. PSFabricDetails.cs 804 (RecoveryServices)
public ASRInMageAzureV2SpecificRPIDetails( InMageAzureV2ReplicationDetails details) { this.LastHeartbeat = this.LastHeartbeat;
Perhatikan tugas kedua dan selanjutnya. Di sisi kanan ekspresi, bukan
ini yang muncul sama sekali, tetapi
detail .
Lihatlah deklarasi properti ini. Properti
LastHeartbeat :
public DateTime? LastHeartbeat { get; set; }
Terakhir, 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 siap mengakui pemicuan ini adalah kesalahan nyata. Tapi apa yang harus dilakukan dengan pemicu berikut? Di dalamnya, tidak seperti dua fragmen kode sebelumnya, ada beberapa penugasan properti untuk diri mereka sendiri. Ini sudah 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 tiga penetapan properti secara berurutan. Untuk berjaga-jaga, saya memberikan deklarasi lengkap dari kelas
RemoveExpressRouteConnectionCommand dengan semua atributnya, serta deklarasi properti
ResourceGroupName (dua properti lainnya dideklarasikan dengan cara yang sama). Memicu yang membuat saya berpikir tentang pertanyaan: "Apakah ini kesalahan?" Saya menduga bahwa beberapa jenis sihir internal pengembangan PowerShell dapat terjadi di sini. Saya berharap di antara pembaca ada ahli yang memiliki pengetahuan dalam hal ini. Saya belum siap untuk membuat kesimpulan 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);
Melewati kata kunci
lemparan . Terlebih lagi, komentar tersebut mengatakan bahwa pengecualian hanya boleh dibuang. Dalam solusi
RecoveryServices , saya menemukan beberapa kesalahan serupa:
- 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 kerja dilanggar. Jika
apiType berisi nilai, maka 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") , dan
apiType.Value.ToString ("g") , masing-masing, 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 paradoks. Dua cek yang saling bertentangan. Mungkin pemeriksaan kesetaraan
nol kedua 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"); } .... }
Memeriksa tidak ada gunanya, dan pengecualian tidak akan pernah dilempar. Kondisi ini membutuhkan persamaan simultan dari variabel
linkedServiceType ke tiga nilai yang berbeda. Operator && dan || mungkin bingung. Kode yang diperbaiki:
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); } .... }
Pemeriksaan
berlebihan variabel
Ekus untuk kesetaraan
nol . Mungkin tidak ada yang salah, tetapi kodenya terlihat jelek.
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); } }
Pemeriksaan berlebihan, atau kondisi yang salah. Memeriksa
RetentionTimes.Count == 0 tidak masuk akal, karena setelah itu periksa
RetentionTimes.Count! = 1 .
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 dalam string format. Kualifikasi
{0} digunakan dua kali, dengan dua argumen diteruskan ke metode
Format . Opsi 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 digunakan tanpa memeriksa
nol . Namun, saat membuat
VirtualMachineScaleSetStorageProfile , variabel ini sudah diperiksa menggunakan operator akses bersyarat, dan dua kali. Kode terlihat tidak 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(....);
Seperti dalam kasus eksekusi normal, dan sebagai hasil dari penanganan pengecualian, variabel yang adaContacts bisa mendapatkan
nol , setelah itu pekerjaan akan dilanjutkan. Lebih lanjut dalam kode variabel ini digunakan tanpa verifikasi.
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 curiga bahwa urutan argumen yang lewat ke 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 sesuatu yang bercampur aduk di sini dengan argumen nomor tujuh dan delapan. Penulis perlu memverifikasi kode.
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 dikirimkan. Sebagai gantinya, mereka mendapatkan GUID baru dan menetapkannya ke bidang
_guid . Saya pikir sebagian besar pembaca akan setuju bahwa kode tersebut terlihat paling jelek. Menggunakan konstruksi semacam itu tidak mudah: untuk (kembali) menginisialisasi properti
GetGuid ,
Anda harus memberinya nilai palsu, yang sama sekali tidak terlihat. Tetapi yang paling utama saya terhibur pada saat bagaimana penulis sendiri menggunakan konstruksi ini. Hanya ada satu tempat dalam kode tempat
GetGuid bekerja . Lihatlah:
public override void ExecuteCmdlet() { .... var itemResponse = ServiceClientAdapter.CreateOrUpdateProtectionIntent( GetGuid ?? Guid.NewGuid().ToString(), ....); .... }
Hebat!
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 menunjukkan kemungkinan kesalahan dalam string yang ditetapkan untuk konstanta
GroupName . Kesimpulannya didasarkan pada analisis empiris penugasan lain dengan mempertimbangkan nama variabel akun. Saya pikir dalam hal ini analisanya benar, dan nilai konstanta
GroupName haruslah "Nama Grup Manajemen". Kesalahan ini mungkin disebabkan oleh fakta bahwa nilai untuk konstanta
GroupId disalin , tetapi mereka lupa untuk mengubahnya.
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 |
Ada kecurigaan bahwa telah terjadi kesalahan, dan operator || juga harus digunakan di antara kondisi terakhir di blok
if . Jawaban yang tepat, seperti yang sering terjadi, hanya dapat diberikan oleh pengembang.
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 Objek digunakan terlebih dahulu, dan hanya kemudian tautan diperiksa untuk
null . Kami
sangat sering menemukan kesalahan seperti itu. 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) .... }
Dan beberapa kesalahan serupa lainnya:
- 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, dalam kode Azure PowerShell, saya bertemu lebih banyak kesalahan V3095 . Tapi mereka semua sangat mirip, jadi saya tidak akan membahas hal ini lebih detail.
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));
Juga jenis kesalahan yang cukup umum. Variabel
startTime diperiksa untuk nilai pada penggunaan pertama. Lain kali Anda menggunakan ini, jangan. Tapi itu bisa lebih buruk. Lihatlah blok
if yang kedua. Saya berpikir bahwa seharusnya tidak ada variabel
startTime sama
sekali . Ini ditunjukkan oleh tidak adanya pemeriksaan untuk keberadaan nilai sebelum digunakan, dan string yang dibentuk untuk meneruskan ke metode
Tambahkan . Bagian pertama dari baris ini menyebutkan variabel lain (
lastModifiedTime ).
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 digunakan dengan tidak aman, meskipun sebelumnya dalam kode ada penggunaan variabel ini dengan pemeriksaan awal untuk
null .
V3125 dalam kode Azure PowerShell bahkan lebih
sukses daripada
V3095 yang dijelaskan sebelumnya. Semuanya juga dari tipe yang sama. Saya pikir kita dapat membatasi diri pada dua yang kita periksa.
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
apiVersionSetId variabel lokal telah diinisialisasi, tetapi belum digunakan. Seringkali pola seperti itu menunjukkan kesalahan. Saya pikir dalam kasus ini probabilitas kesalahan tinggi, mengingat bahwa nama
apiVersionSetId variabel lokal dan nama properti
ApiVersionSetId hanya berbeda dalam kasus huruf pertama. Lihatlah kodenya. Setelah menginisialisasi
apiVersionSetId (dengan satu atau lain cara), maka hanya properti
ApiVersionSetId yang digunakan dalam kode. Sangat, 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);
Situasi, hampir persis mengulangi yang sebelumnya dipertimbangkan.
CacheId variabel lokal tidak digunakan setelah inisialisasi. Sebagai gantinya, mereka menggunakan properti dengan nama yang sangat mirip,
CacheId . Saya tidak tahu, mungkin ini adalah pola di antara pengembang Azure PowerShell. Tapi itu terlihat seperti 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 dinyatakan seperti ini:
Berlawanan dengan nama solusi di mana kesalahan ini terdeteksi (LogicApp), saya tidak melihat logika di sini. Menggunakan
nilai dalam setter untuk merekam bukan kejadian langka, tetapi dalam kasus ini kita berbicara tentang kehilangan nilai aslinya. Terlihat aneh. Kode memiliki akses baca tunggal ke properti ini. Mungkin Anda harus mencari nasihat ahli lagi. Mungkin saya tidak mengerti sesuatu. Faktanya adalah bahwa saya bertemu beberapa pola yang sama persis:
- 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
Itu semua bug menarik yang ditemukan dalam kode Azure PowerShell.
Penggemar dan hanya tertarik, saya sarankan melakukan studi independen tentang kesalahan dalam kode proyek ini (atau lainnya). Saya mungkin bisa melewatkan sesuatu yang menarik. Untuk melakukan ini, cukup unduh dan instal PVS-Studio .Terima kasih sudah membaca. Kode tanpa kode!
Jika Anda ingin berbagi artikel ini dengan audiens yang berbahasa Inggris, silakan gunakan tautan ke terjemahan: Sergey Khrenov.
Azure PowerShell: Kebanyakan Tidak Berbahaya .