Hallo an alle. Heute haben wir ein weiteres Microsoft-Projekt im Test. Anhand des Titels des Artikels können Sie erraten, dass die Entwickler uns diesmal nicht mit einer großen Anzahl von Fehlern zufrieden stellen konnten. Wir hoffen, dass die Autoren des Projekts nicht durch den Namen beleidigt werden. Immerhin ist eine kleine Anzahl von Fehlern ausgezeichnet, nicht wahr? Im Azure PowerShell-Code wurde jedoch etwas Interessantes gefunden. Wir empfehlen Ihnen, sich mit den Funktionen dieses Projekts vertraut zu machen und sich die Fehler anzusehen, die mit dem PV # C-Analysator PVS-Studio festgestellt wurden.
Über das Projekt
Azure PowerShell ist ein Cmdlet, mit dem Sie
Azure- Ressourcen direkt über die
PowerShell- Befehlszeile verwalten können. Der Hauptzweck dieses Sets besteht darin, das Lernen und den schnellen Start der Entwicklung für Azure zu vereinfachen. Azure PowerShell bietet Administratoren und Entwicklern leistungsstarke Funktionen zum Erstellen, Bereitstellen und Verwalten von Microsoft Azure-Anwendungen.
Azure PowerShell wurde in der .NET Standard-Umgebung entwickelt und wird von PowerShell 5.1 für Windows und PowerShell 6.x und höher für alle Plattformen unterstützt. Azure PowerShell-
Quellcode ist auf GitHub verfügbar.
In letzter Zeit bin ich häufig auf Microsoft-Projekte aufmerksam geworden. Meiner Meinung nach ist die Qualität dieser Projekte normalerweise am besten. Obwohl natürlich nicht ohne Ausnahmen, wie der Artikel "
WinForms: Fehler, Holmes ". Diesmal ist jedoch alles normal. Das Projekt ist groß: 6845-Dateien .cs-Quellcode enthalten ungefähr 700.000 Zeilen, ausgenommen leere (Tests sowie Warnungen vor der dritten Zuverlässigkeitsstufe habe ich nicht berücksichtigt). Es gab nur sehr wenige Fehler für ein solches Codevolumen: nicht mehr als hundert. Es gibt einige Situationen des gleichen Typs, daher habe ich für den Artikel die interessantesten Positiven ausgewählt. Fehler werden wie üblich nach den PVS-Studio-Diagnosenummern sortiert.
Ich bin auch auf Codefragmente gestoßen, die wie Fehler aussehen, aber ich konnte keine eindeutige Schlussfolgerung über das Vorhandensein eines echten Problems ziehen, da ich mit den Designfunktionen für PowerShell nicht ausreichend vertraut bin. Ich hoffe, dass es unter den Lesern Experten in dieser Angelegenheit gibt und mir helfen wird. Darüber unten.
Vor dem Beginn der „Nachbesprechung“ stelle ich das Designmerkmal in Bezug auf seine Struktur fest. Der Azure PowerShell-Quellcode besteht aus mehr als siebzig Visual Studio-Lösungen. Einige Lösungen umfassen Projekte aus anderen Lösungen. Eine solche Struktur verlangsamte die Analyse ein wenig (nicht viel). Der Rest der Überprüfung verursachte keine Schwierigkeiten. Der Einfachheit halber werde ich in der Zeile der Fehlermeldung (in Klammern) den Namen der Lösung angeben, in der dieser Fehler erkannt wurde.
Validierungsergebnisse
V3001 Links und rechts vom '||' befinden sich identische Unterausdrücke 'strTimespan.Contains ("M")'. Betreiber. 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")) .... }
Ein Beispiel für einen ziemlich offensichtlichen Fehler, den nur der Entwickler beheben kann. In diesem Fall ist es völlig unverständlich, ob es sich um eine Vervielfältigung von Code handelt, die nichts beeinflusst, oder ob anstelle von
"M" etwas anderes in einer der letzten beiden Prüfungen erscheinen sollte.
V3001 Links und rechts vom Operator '&&' befinden sich identische Unterausdrücke 'this.AggregationType! = Null'. 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; .... }
Hier liegt wahrscheinlich kein Fehler vor. Dies ist ein Beispiel für redundanten Code. Manchmal weist ein solcher Code auf ein unzureichendes Entwicklerwissen hin. Tatsache ist, dass
this.AggregationType! = Null und
this.AggregationType.HasValue-Prüfungen identisch sind. Es reicht aus, einen von ihnen (einen beliebigen) zu verwenden. Persönlich bevorzuge ich die
Option HasValue :
string aggregation = this.AggregationType.HasValue ? this.AggregationType.Value.ToString() : null;
V3003 Die Verwendung des
Musters 'if (A) {...} else if (A) {...}' wurde erkannt. Es besteht die Wahrscheinlichkeit eines logischen Fehlers. Überprüfen Sie die Zeilen: 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 ); } .... }
Die beiden
anderen if- Blöcke sind absolut identisch, einschließlich des Zustands und des Körpers des Blocks. Solche Fehler treten normalerweise auf, wenn die Copy-Paste-Methode in der Arbeit verwendet wird. Die Frage ist wiederum die Kritikalität dieses Fehlers. Wenn dies keine einfache Vervielfältigung von Code ist, können wir über das Fehlen der erforderlichen Überprüfung und die entsprechenden Maßnahmen sprechen. Der Autor muss den Code bearbeiten.
V3005 Die Variable 'this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent' wird sich selbst zugewiesen. SetAzureVMOperatingSystemCommand.cs 298 (Compute)
public override void ExecuteCmdlet() { ....
Der Wert der Eigenschaft wird sich selbst zugewiesen. Schauen Sie sich seine Anzeige an:
[JsonProperty(PropertyName = "provisionVMAgent")] public bool? ProvisionVMAgent { get; set; }
In der
JsonProperty- Beschreibung heißt es: "Weist den Newtonsoft.Json.JsonSerializer an, das Mitglied immer mit dem angegebenen Namen zu serialisieren." Es scheint, dass alles einfach ist und es einen offensichtlichen Fehler gibt. Verwirrend ist auch die explizite Verwendung
dieser Option für den Zugriff auf eine Eigenschaft. Möglicherweise wurde stattdessen versehentlich keine andere Variable angegeben. Wir werden jedoch vorerst keine Schlussfolgerungen ziehen. Tatsache ist, dass ich im Azure PowerShell-Code viele solcher Zuweisungen getroffen habe (die Eigenschaft ist sich selbst zugewiesen). Hier ist ein weiteres Beispiel für eine Zuweisung, die einem Fehler sehr ähnlich ist:
V3005 Die Variable 'this.LastHeartbeat' wird sich selbst zugewiesen. PSFabricDetails.cs 804 (RecoveryServices)
public ASRInMageAzureV2SpecificRPIDetails( InMageAzureV2ReplicationDetails details) { this.LastHeartbeat = this.LastHeartbeat;
Achten Sie auf die zweite und die nachfolgenden Aufgaben. Auf der rechten Seite des Ausdrucks erscheint überhaupt nicht
dies , sondern
Details . Schauen
Sie sich die Deklaration
dieser Eigenschaft an.
LastHeartbeat :
public DateTime? LastHeartbeat { get; set; }
Suchen Sie abschließend in der
InMageAzureV2ReplicationDetails- Klasse nach einer gleichnamigen Eigenschaft. Eine solche Eigenschaft wird dort deklariert:
public class InMageAzureV2ReplicationDetails : ReplicationProviderSpecificSettings { .... [JsonProperty(PropertyName = "lastHeartbeat")] public DateTime? LastHeartbeat { get; set; } .... }
Nun, in diesem Fall bin ich bereit zuzugeben, dass diese Auslösung ein echter Fehler ist. Aber was tun mit den folgenden Auslösern? In ihnen gibt es im Gegensatz zu den beiden vorherigen Codefragmenten eine mehrfache Zuordnung von Eigenschaften zu sich selbst. Dies ist schon weniger wie ein Fehler:
- V3005 Die Variable 'this.ResourceGroupName' wird sich selbst zugewiesen. RemoveAzureRmExpressRouteConnectionCommand.cs 84 (CognitiveServices)
- V3005 Die Variable 'this.ExpressRouteGatewayName' wird sich selbst zugewiesen. RemoveAzureRmExpressRouteConnectionCommand.cs 85 (CognitiveServices)
- V3005 Die Variable 'this.Name' wird sich selbst zugewiesen. 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; } .... } .... }
Die
Execute- Methode enthält drei aufeinanderfolgende Zuweisungen von Eigenschaften an sich selbst. Für alle Fälle habe ich eine vollständige Deklaration der
RemoveExpressRouteConnectionCommand- Klasse mit all ihren Attributen sowie eine Deklaration der
ResourceGroupName- Eigenschaft angegeben (die beiden anderen Eigenschaften werden auf dieselbe Weise deklariert). Es war eine solche Auslösung, die mich über die Frage nachdenken ließ: "Ist das ein Fehler?" Ich vermute, dass hier eine Art interne Magie der PowerShell-Entwicklung auftreten kann. Ich hoffe, dass es unter den Lesern Experten gibt, die sich in dieser Angelegenheit auskennen. Ich bin nicht bereit, in diesem Fall eine Schlussfolgerung zu ziehen.
V3006 Das Objekt wurde erstellt, wird jedoch nicht verwendet. Das Schlüsselwort 'throw' könnte fehlen: throw new ArgumentException (FOO). StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 259 (RecoveryServices)
private void StartRPITestFailover() { .... if (....) { .... } else { new ArgumentException( Resources .UnsupportedDirectionForTFO);
Das Schlüsselwort
throw wurde übersprungen. Darüber hinaus heißt es in dem Kommentar, dass die Ausnahme nur ausgelöst werden sollte. In der
RecoveryServices- Lösung sind mehrere ähnliche Fehler aufgetreten:
- V3006 Das Objekt wurde erstellt, wird jedoch nicht verwendet. Das Schlüsselwort 'throw' könnte fehlen: throw new ArgumentException (FOO). StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 305 (RecoveryServices)
- V3006 Das Objekt wurde erstellt, wird jedoch nicht verwendet. Das Schlüsselwort 'throw' könnte fehlen: throw new ArgumentException (FOO). StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 278 (RecoveryServices)
- V3006 Das Objekt wurde erstellt, wird jedoch nicht verwendet. Das Schlüsselwort 'throw' könnte fehlen: throw new ArgumentException (FOO). StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 322 (RecoveryServices)
- V3006 Das Objekt wurde erstellt, wird jedoch nicht verwendet. Das Schlüsselwort 'throw' könnte fehlen: throw new ArgumentException (FOO). UpdateAzureRmRecoveryServicesAsrProtectionDirection.cs 421 (RecoveryServices)
- V3006 Das Objekt wurde erstellt, wird jedoch nicht verwendet. Das Schlüsselwort 'throw' könnte fehlen: throw new ArgumentException (FOO). UpdateAzureRmRecoveryServicesAsrProtectionDirection.cs 452 (RecoveryServices)
V3022 Der Ausdruck 'apiType.HasValue' ist immer falsch. 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 ?
Die Logik der Arbeit wird verletzt. Wenn
apiType einen Wert enthält, erreicht das Steuerelement den
Rückgabeausdruck am Ende der Methode nicht (alle
Switch- Zweige enthalten
return ). Andernfalls gibt die Methode immer
PsApiManagementApiType.Http.ToString ("g") bzw.
apiType.Value.ToString ("g") zurück.
V3022 Der Ausdruck 'automationJob! = Null && automationJob == null' ist immer falsch. NodeConfigurationDeployment.cs 199 (Automatisierung)
public NodeConfigurationDeployment( ...., Management.Automation.Models.Job automationJob = null, ....) { .... if (automationJob != null && automationJob == null) return; .... }
Der paradoxe Code. Zwei Schecks, die sich widersprechen. Wahrscheinlich enthält die zweite
Nullgleichheitsprüfung die falsche Variable.
V3022 Ausdruck ist immer falsch. 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"); } .... }
Das Überprüfen ist sinnlos und eine Ausnahme wird niemals ausgelöst. Die Bedingung erfordert die gleichzeitige Gleichheit der Variable
linkedServiceType mit drei verschiedenen Werten. Die Operatoren && und || sind wahrscheinlich verwirrt. Korrigierter Code:
if (( linkedServiceType == LinkedServiceType.OnPremisesSqlLinkedService || linkedServiceType == LinkedServiceType.OnPremisesOracleLinkedService || linkedServiceType == LinkedServiceType.OnPremisesFileSystemLinkedService) && (value == null || value.Length == 0)) ....
V3022 Der Ausdruck 'Ekus == null' ist immer falsch. PSKeyVaultCertificatePolicy.cs 129 (KeyVault)
internal CertificatePolicy ToCertificatePolicy() { .... if (Ekus != null) { x509CertificateProperties.Ekus = Ekus == null ? null : new List<string>(Ekus); } .... }
Überflüssige Überprüfung der
Ekus- Variablen auf Gleichheit
null . Wahrscheinlich nichts falsch, aber der Code sieht hässlich aus.
V3023 Überprüfen Sie diesen Ausdruck. Der Ausdruck ist übertrieben oder enthält einen Druckfehler. PolicyRetentionObjects.cs 207 (RecoveryServices)
public virtual void Validate() { if (RetentionTimes == null || RetentionTimes.Count == 0 || RetentionTimes.Count != 1) { throw new ArgumentException( Resources.InvalidRetentionTimesInPolicyException); } }
Übermäßige Überprüfung oder fehlerhafter Zustand. Das Überprüfen von
RetentionTimes.Count == 0 macht keinen Sinn, da danach
RetentionTimes.Count! = 1 überprüft wird.
V3025 Falsches Format. Beim Aufrufen der Funktion 'Format' wird eine andere Anzahl von Formatelementen erwartet. Nicht verwendete Argumente: 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))) { .... } .... }
Fehler in der Formatzeichenfolge. Das Qualifikationsmerkmal
{0} wird zweimal verwendet, wobei zwei Argumente an die
Format- Methode übergeben werden. Die richtige Option:
if (this.ShouldProcess(this.Name, string.Format("Creating Log Alert Rule '{0}' in resource group {1}", this.Name, this.ResourceGroupName))) ....
Ein weiterer ähnlicher Fehler:
- V3025 Falsches Format. Beim Aufrufen der Funktion 'Format' wird eine andere Anzahl von Formatelementen erwartet. Nicht verwendete Argumente: this.ResourceGroupName. RemoveScheduledQueryRuleCommand.cs 88 (Monitor)
V3042 Mögliche NullReferenceException. Das '?.' und '.' Operatoren werden für den Zugriff auf Mitglieder des Objekts 'imageAndOsType' VirtualMachineScaleSetStrategy.cs 81 (Compute) verwendet.
internal static ResourceConfig<VirtualMachineScaleSet> CreateVirtualMachineScaleSetConfig(...., ImageAndOsType imageAndOsType, ....) { .... VirtualMachineProfile = new VirtualMachineScaleSetVMProfile { OsProfile = new VirtualMachineScaleSetOSProfile { ...., WindowsConfiguration = imageAndOsType.CreateWindowsConfiguration(),
Beim Erstellen eines
VirtualMachineScaleSetVMProfile- Objekts wird die Variable
imageAndOsType verwendet, ohne nach
Null zu suchen . Beim Erstellen von
VirtualMachineScaleSetStorageProfile wird diese Variable jedoch bereits zweimal mit dem Operator für den bedingten Zugriff überprüft. Der Code sieht unsicher aus.
V3042 Mögliche NullReferenceException. Das '?.' und '.' Operatoren werden für den Zugriff auf Mitglieder des Objekts 'availableContacts' verwendet. 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(....);
Wie bei der normalen Ausführung und als Ergebnis der Behandlung der Ausnahme kann die
vorhandene Variable "Contacts"
null werden.
Danach wird die Arbeit fortgesetzt. Weiter im Code wird diese Variable ohne Überprüfung verwendet.
V3066 Möglicherweise falsche Reihenfolge der an die Methode 'PersistSyncServerRegistration' übergebenen Argumente: 'storageSyncServiceUid' und 'DiscoveryUri'. EcsManagementInteropClient.cs 364 (StorageSync)
public class EcsManagementInteropClient : IEcsManagement { .... public int PersistSyncServerRegistration(....) { return m_managementObject.PersistSyncServerRegistration( serviceUri, subscriptionId, storageSyncServiceName, resourceGroupName, clusterId, clusterName, storageSyncServiceUid,
Der Analysator vermutete, dass die Reihenfolge der Übergabe von Argumenten an die
PersistSyncServerRegistration- Methode
verwirrt war . Methodenerklärung:
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,
In der Tat ist hier etwas mit den Argumenten Nummer sieben und acht verwechselt. Die Überprüfung des Codes durch den Autor ist erforderlich.
V3077 Der Setter der Eigenschaft 'GetGuid' verwendet seinen Parameter 'value' nicht. RecoveryServicesBackupCmdletBase.cs 54 (RecoveryServices)
public abstract class RecoveryServicesBackupCmdletBase : AzureRMCmdlet { .... static string _guid; protected static string GetGuid { get { return _guid; } set { _guid = Guid.NewGuid().ToString(); } } .... }
Der Setter verwendet den übertragenen Parameter nicht. Stattdessen erhalten sie eine neue GUID und weisen sie dem Feld
_guid zu. Ich denke, die meisten Leser werden zustimmen, dass ein solcher Code zumindest hässlich aussieht. Die Verwendung einer solchen Konstruktion ist nicht ganz praktisch:
Um die
GetGuid- Eigenschaft (neu) zu initialisieren, müssen
Sie ihr einen falschen Wert zuweisen, der völlig offensichtlich ist. Vor allem aber hat mich der Moment amüsiert, wie die Autoren selbst diese Konstruktion verwenden. Es gibt nur eine Stelle im Code, an der
GetGuid funktioniert . Schauen Sie mal rein:
public override void ExecuteCmdlet() { .... var itemResponse = ServiceClientAdapter.CreateOrUpdateProtectionIntent( GetGuid ?? Guid.NewGuid().ToString(), ....); .... }
Großartig!
V3091 Empirische Analyse. Möglicherweise ist im Zeichenfolgenliteral ein Tippfehler vorhanden: "Verwaltungsgruppen-ID". Das 'Id'-Wort ist verdächtig. Constants.cs 36 (Ressourcen)
public class HelpMessages { public const string SubscriptionId = "Subscription Id of the subscription associated with the management"; public const string GroupId = "Management Group Id";
Der Analysator hat einen möglichen Fehler in der zugewiesenen Zeichenfolge für die
GroupName- Konstante
angezeigt . Die Schlussfolgerung basiert auf einer empirischen Analyse anderer Zuordnungen unter Berücksichtigung von Variablennamen. Ich denke, dass in diesem Fall der Analysator richtig ist und der Wert der
GroupName- Konstante die Form „Management Group name“ haben sollte. Der Fehler wurde wahrscheinlich dadurch verursacht, dass der Wert für die
GroupId- Konstante
kopiert wurde, sie jedoch vergessen haben, ihn zu ändern.
Ein weiterer ähnlicher Fehler:
- V3091 Empirische Analyse. Möglicherweise ist im Zeichenfolgenliteral ein Tippfehler vorhanden. Das Wort 'Name' ist verdächtig. ParamHelpMsgs.cs 153 (RecoveryServices)
V3093 Das '|' Der Operator wertet beide Operanden aus. Vielleicht ein Kurzschluss '||' Stattdessen sollte der Operator verwendet werden. PSKeyVaultCertificatePolicy.cs 114 (KeyVault)
internal CertificatePolicy ToCertificatePolicy() { .... if (!string.IsNullOrWhiteSpace(SubjectName) || DnsNames != null || Ekus != null || KeyUsage != null |
Es besteht der Verdacht, dass ein Fehler aufgetreten ist, und der Operator || sollte auch zwischen den letzten Bedingungen im
if- Block verwendet werden. Die genaue Antwort kann, wie so oft, nur vom Entwickler gegeben werden.
V3095 Das 'Zertifikat'-Objekt wurde verwendet, bevor es gegen Null verifiziert wurde. Überprüfen Sie die Zeilen: 41, 43. CertificateInfo.cs 41 (Automatisierung)
public CertificateInfo( ...., Azure.Management.Automation.Models.Certificate certificate) { .... this.Name = certificate.Name; if (certificate == null) return; .... }
Klassisch Das Objekt wird zuerst verwendet, und erst dann wird der Link auf
null geprüft. Wir stoßen
sehr oft auf solche Fehler. Betrachten Sie einen anderen ähnlichen Fehler.
V3095 Das Objekt 'clusterCred' wurde verwendet, bevor es gegen null verifiziert wurde. Überprüfen Sie die Zeilen: 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) .... }
Und noch ein paar ähnliche Fehler:
- V3095 Das Objekt '_profile' wurde verwendet, bevor es gegen null verifiziert wurde. Überprüfen Sie die Zeilen: 47, 49. RMProfileClient.cs 47 (Konten)
- V3095 Das Objekt 'this.LoadBalancer.BackendAddressPools' wurde verwendet, bevor es gegen null verifiziert wurde. Überprüfen Sie die Zeilen: 56, 63. AddAzureRmLoadBalancerBackendAddressPoolConfigCommand.cs 56 (CognitiveServices)
- Im Azure PowerShell-Code sind im Allgemeinen viel mehr V3095- Fehler aufgetreten . Aber sie sind sich alle ziemlich ähnlich, deshalb werde ich nicht näher darauf eingehen.
V3125 Das 'startTime'-Objekt wurde verwendet, nachdem es gegen null verifiziert wurde. Überprüfen Sie die Zeilen: 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));
Auch eine ziemlich häufige Art von Fehler. Die Variable
startTime wurde bei der ersten Verwendung auf den Wert überprüft. Wenn Sie dies das nächste Mal verwenden, tun Sie dies nicht. Aber es könnte noch schlimmer sein. Schauen Sie sich den zweiten
if- Block an. Ich denke, dass es überhaupt keine
startTime- Variable geben sollte. Dies wird sowohl durch das Fehlen der Überprüfung auf das Vorhandensein eines Werts vor der Verwendung als auch durch die Zeichenfolge angezeigt, die zum Übergeben an die
Add- Methode gebildet wurde. Der erste Teil dieser Zeile erwähnt eine andere Variable (
lastModifiedTime ).
V3125 Das 'firstPage'-Objekt wurde verwendet, nachdem es gegen null verifiziert wurde. Überprüfen Sie die Zeilen: 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))
Ein weiterer offensichtlicher Fehler. Die Variable
firstPage wird unsicher verwendet, obwohl diese Variable früher im Code mit einer vorläufigen Prüfung auf
null verwendet wird .
V3125 im Azure PowerShell-Code war noch
erfolgreicher als
V3095, wie zuvor beschrieben. Alle von ihnen sind auch vom gleichen Typ. Ich denke, wir können uns auf die beiden beschränken, die wir untersucht haben.
V3137 Die Variable 'apiVersionSetId' wird zugewiesen, aber am Ende der Funktion nicht verwendet. 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))
Der Analysator meldet, dass die lokale Variable
apiVersionSetId initialisiert, aber nicht verwendet wurde. Oft zeigt ein solches Muster einen Fehler an. Ich denke, in diesem Fall ist die Fehlerwahrscheinlichkeit hoch, da sich der Name der lokalen Variablen
apiVersionSetId und der Name der Eigenschaft
ApiVersionSetId nur im Fall des ersten Buchstabens unterscheiden. Schauen Sie sich den Code an. Nach der Initialisierung von
apiVersionSetId (auf die eine oder andere Weise) wird im Code nur die
ApiVersionSetId- Eigenschaft verwendet. Sehr, sehr verdächtig.
V3137 Die Variable 'cacheId' wird zugewiesen, aber am Ende der Funktion nicht verwendet. 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);
Die Situation wiederholt fast genau die zuvor betrachtete. Die lokale Variable
cacheId wird nach der Initialisierung nicht verwendet. Stattdessen verwenden sie eine Eigenschaft mit einem sehr ähnlichen Namen,
CacheId . Ich weiß nicht, vielleicht ist dies ein solches Muster unter Azure PowerShell-Entwicklern. Aber es sieht nach einem Fehler aus.
V3143 Der Parameter 'value' wird in einem Eigenschaftssetter neu geschrieben und danach nicht mehr verwendet. 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; }
Das Feld
partnerType wird wie
folgt deklariert:
Im Gegensatz zum Namen der Lösung, in der dieser Fehler erkannt wurde (LogicApp), sehe ich die Logik hier nicht. Die Verwendung von
Wert in einem Setter für die Aufzeichnung ist nicht so selten, aber in diesem Fall geht es darum, den ursprünglichen Wert zu verlieren. Es sieht komisch aus. Der Code hat einen einzigen Lesezugriff auf diese Eigenschaft. Vielleicht sollten Sie sich erneut von Experten beraten lassen. Vielleicht verstehe ich etwas nicht. Tatsache ist, dass ich noch ein paar der exakt gleichen Muster getroffen habe:
- V3143 Der Parameter 'value' wird in einem Eigenschaftssetter neu geschrieben und danach nicht mehr verwendet. NewAzureIntegrationAccountSchemaCommand.cs 79 (LogicApp)
- V3143 Der Parameter 'value' wird in einem Eigenschaftssetter neu geschrieben und danach nicht mehr verwendet. NewAzureIntegrationAccountSchemaCommand.cs 87 (LogicApp)
- V3143 Der Parameter 'value' wird in einem Eigenschaftssetter neu geschrieben und danach nicht mehr verwendet. UpdateAzureIntegrationAccountPartnerCommand.cs 67 (LogicApp)
- V3143 Der Parameter 'value' wird in einem Eigenschaftssetter neu geschrieben und danach nicht mehr verwendet. UpdateAzureIntegrationAccountSchemaCommand.cs 80 (LogicApp)
- V3143 Der Parameter 'value' wird in einem Eigenschaftssetter neu geschrieben und danach nicht mehr verwendet. UpdateAzureIntegrationAccountSchemaCommand.cs 88 (LogicApp)
Fazit
Das sind all die interessanten Fehler, die im Azure PowerShell-Code gefunden wurden. Enthusiasten und nur interessiert, schlage ich vor, eine unabhängige Untersuchung der Fehler im Code dieses (oder eines anderen) Projekts durchzuführen. Ich hätte wahrscheinlich etwas anderes Interessantes verpassen können. Laden Sie dazu einfach PVS-Studio herunter und installieren Sie es .Danke fürs Lesen. Ein codeloser Code!
Wenn Sie diesen Artikel einem englischsprachigen Publikum zugänglich machen möchten, verwenden Sie bitte den Link zur Übersetzung: Sergey Khrenov.
Azure PowerShell: Meist harmlos .