Azure PowerShell:大部分无害

图片6

大家好 今天,我们正在检查另一个Microsoft项目。 通过本文的标题,您可以猜测这次开发人员并没有“请”我们很多错误。 我们希望项目的作者不会因标题而受到冒犯。 毕竟,少数错误是巨大的,不是吗? 但是,我们仍然设法在Azure PowerShell代码中找到了一些有趣的东西。 我们建议您了解该项目的功能并检查使用PVS-Studio C#分析仪发现的错误。

关于项目


Azure PowerShell是一组命令集( cmdlet ),可让您直接从PowerShell命令行管理Azure资源。 该集合的主要目的是简化学习过程并快速开始Azure的开发。 Azure PowerShell为管理员和开发人员提供了引人注目的功能,以创建,部署和管理Microsoft Azure应用程序。

Azure PowerShell在.NET Standard环境中开发,适用于Windows的PowerShell 5.1和适用于所有平台的PowerShell 6.x及更高版本均支持。 GitHub上提供了Azure PowerShell 源代码

最近,我经常去检查Microsoft项目。 在我看来,这些项目的质量通常是一流的。 虽然,当然,并非没有例外,如文章“ WinForms:Errors,Holmes ”中所述。 但是这次一切都很好。 该项目非常庞大:6845 .cs源代码文件包含大约700,000行,不包括空白行(我没有考虑测试和第三确定性的警告)。 对于这样的代码量,发现的错误很少:不超过一百。 有很多类似的案例,所以我选择了最有趣的案例。 通常,我按照PVS-Studio警告编号对错误进行排序。

另外,我偶然发现了一些看起来像错误的代码片段,但是由于我对PowerShell开发的特性还不够熟悉,因此无法将其视为绝对错误。 我希望读者中有这个问题的专家能够为我提供帮助。 我将在下面详细描述。

在反馈部分之前,我想提到项目的具体结构。 Azure PowerShell源代码包含70多个Visual Studio解决方案。 一些解决方案包括其他解决方案。 这种结构使分析速度有所降低(不多)。 支票仍然没有造成任何其他困难。 为了方便起见,在错误消息中(在括号中),我将指定发现错误的解决方案的名称。

分析结果


V3001在'||'的左侧和右侧有相同的子表达式'strTimespan.Contains(“ M”)'。 操作员。 AzureServiceBusCmdletBase.cs 187(事件网格)

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")) .... } 

只有开发人员才能解决的一个明显错误的示例。 在这种情况下,绝对不清楚我们是否要处理不影响任何内容的代码重复,或者是否必须进行其他操作,而不是在最后两个检查之一中代替“ M”

V3001在'&&'运算符的左侧和右侧有相同的子表达式'this.AggregationType!= Null'。 GetAzureRmMetricCommand.cs 156(监控器)

 public AggregationType? AggregationType { get; set; } .... protected override void ProcessRecordInternal() { .... string aggregation = (this.AggregationType != null && this.AggregationType.HasValue) ? this.AggregationType.Value.ToString() : null; .... } 

这里可能没有错误。 这是冗余代码的示例。 有时,这样的代码可能表明开发人员缺乏知识。 关键是检查this.AggregationType!= Nullthis.AggregationType.HasValue是否相同。 仅使用其中之一(任意一个)就足够了。 就个人而言,我更喜欢HasValue的选项

 string aggregation = this.AggregationType.HasValue ? this.AggregationType.Value.ToString() : null; 

V3003检测到使用'if(A){...} else if(A){...}'模式。 存在逻辑错误的可能性。 检查行: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 ); } .... } 

其他两个if块绝对相同,包括块的条件和主体。 使用复制粘贴方法时通常会发生此类错误。 问题再次出在错误的严重性上。 如果不是简单的代码重复,则可能是缺少所需的检查和适当的操作集。 作者肯定必须编辑代码。

V3005已将 “ this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent”变量分配给它自己。 SetAzureVMOperatingSystemCommand.cs 298(计算)

 public override void ExecuteCmdlet() { .... // OS Profile this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent = this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent; .... } 

该属性的值是自定义的。 看一下它的声明:

 [JsonProperty(PropertyName = "provisionVMAgent")] public bool? ProvisionVMAgent { get; set; } 

JsonProperty描述指出:“指示Newtonsoft.Json.JsonSerializer始终序列化具有指定名称的成员。” 似乎一切都毫无道理,并且已经犯了明显的错误。 显式使用属性来访问属性也很令人困惑。 也许,没有错误地指定了另一个变量来代替这个。 但是,让我们不要下结论。 事实是,我遇到了很多这样的分配(属性是自分配的)。 这是一个分配示例,非常类似于错误:

V3005将'this.LastHeartbeat'变量分配给它自己。 PSFabricDetails.cs 804(RecoveryServices)

 public ASRInMageAzureV2SpecificRPIDetails( InMageAzureV2ReplicationDetails details) { this.LastHeartbeat = this.LastHeartbeat; // <= this.RecoveryAvailabilitySetId = details.RecoveryAvailabilitySetId; this.AgentVersion = details.AgentVersion; this.DiscoveryType = details.DiscoveryType; .... } 

让我们仔细看看第二个和后续的任务。 在表达式的右侧,代替了细节 现在查看this.LastHeartbeat属性的声明:
 public DateTime? LastHeartbeat { get; set; } 

最后,让我们在InMageAzureV2ReplicationDetails类中找到具有相同名称的属性。 此类属性在此处声明:

 public class InMageAzureV2ReplicationDetails : ReplicationProviderSpecificSettings { .... [JsonProperty(PropertyName = "lastHeartbeat")] public DateTime? LastHeartbeat { get; set; } .... } 

好吧,在这种情况下,我愿意承认这是一个真正的错误。 但是接下来的警告该怎么办? 与之前的两个代码片段不同,它具有多个自分配的属性。 好吧,这看起来不像是一个错误:

  • V3005将'this.ResourceGroupName'变量分配给它自己。 RemoveAzureRmExpressRouteConnectionCommand.cs 84(CognitiveServices)
  • V3005将'this.ExpressRouteGatewayName'变量分配给它自己。 RemoveAzureRmExpressRouteConnectionConnectionCommand.cs 85(CognitiveServices)
  • V3005将'this.Name'变量分配给它自己。 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; } .... } .... } 

Execute方法连续包含三个属性的自赋值。 以防万一,我引用了类RemoveExpressRouteConnectionCommand的完整声明及其所有属性,以及ResourceGroupName属性声明(其他两个属性以类似的方式声明)。 正是这些警告使我思考了一个问题:“这是一个错误吗?” 我怀疑,PowerShell开发的某些内部魔术可能正在这里发生。 我希望读者中会有专家了解此问题。 我不准备在这种情况下得出任何结论。

V3006已创建对象, 但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 259(RecoveryServices)

 private void StartRPITestFailover() { .... if (....) { .... } else { new ArgumentException( Resources .UnsupportedDirectionForTFO); // Throw Unsupported Direction // Exception } .... } 

throw关键字被省略。 评论说必须抛出异常。 我在RecoveryServices解决方案中遇到了更多类似的错误:

  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 305(RecoveryServices)
  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 278(RecoveryServices)
  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 322(RecoveryServices)
  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 UpdateAzureRmRecoveryServicesAsrProtectionDirection.cs 421(RecoveryServices)
  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 UpdateAzureRmRecoveryServicesAsrProtectionDirection.cs 452(RecoveryServices)

V3022表达式“ apiType.HasValue”始终为false。 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 ? // <= apiType.Value.ToString("g") : PsApiManagementApiType.Http.ToString("g"); } 

工作的逻辑被打破了。 如果apiType包含一个值,则控件将不会在方法末尾到达return表达式(所有switch分支均包含return )。 否则,该方法将始终返回PsApiManagementApiType.Http.ToString(“ g”) ,而apiType.Value.ToString(“ g”)值将永远不会返回。

V3022表达式'automationJob!= Null && automationJob == null'始终为false。 NodeConfigurationDeployment.cs 199(自动化)

 public NodeConfigurationDeployment( ...., Management.Automation.Models.Job automationJob = null, ....) { .... if (automationJob != null && automationJob == null) return; .... } 

违反直觉的代码。 两项相互矛盾的检查。 第二次检查null可能包含错误的变量。

V3022表达式始终为假。 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"); } .... } 

该检查是没有意义的,并且永远不会引发异常。 该条件要求将linkedServiceType变量的相等性同时设为三个不同的值。 运算符&&和|| 可能会感到困惑。 固定代码:

 if (( linkedServiceType == LinkedServiceType.OnPremisesSqlLinkedService || linkedServiceType == LinkedServiceType.OnPremisesOracleLinkedService || linkedServiceType == LinkedServiceType.OnPremisesFileSystemLinkedService) && (value == null || value.Length == 0)) .... 

V3022表达式'Ekus == null'始终为false。 PSKeyVaultCertificatePolicy.cs 129(KeyVault)

 internal CertificatePolicy ToCertificatePolicy() { .... if (Ekus != null) { x509CertificateProperties.Ekus = Ekus == null ? null : new List<string>(Ekus); } .... } 

Ekus变量进行冗余检查是否为null 。 可能很好,但是代码看起来不太好。

V3023考虑检查此表达式。 表达式过多或打印错误。 PolicyRetentionObjects.cs 207(RecoveryServices)

 public virtual void Validate() { if (RetentionTimes == null || RetentionTimes.Count == 0 || RetentionTimes.Count != 1) { throw new ArgumentException( Resources.InvalidRetentionTimesInPolicyException); } } 

这是过度检查或过度状况。 检查RetentionTimes.Count == 0是没有意义的,因为之后,检查RetentionTimes.Count!= 1

V3025格式错误。 调用“格式”功能时,期望格式项目的数量不同。 未使用的参数:this.ResourceGroupName。 NewScheduledQueryRuleCommand.cs 117(监控器)

 protected override void ProcessRecordInternal() { .... if (this.ShouldProcess(this.Name, string.Format("Creating Log Alert Rule '{0}' in resource group {0}", this.Name, this.ResourceGroupName))) { .... } .... } 

格式化行中有错误。 说明符{0}被使用两次,并且Format方法被传递了两个参数。 这是正确的版本:

 if (this.ShouldProcess(this.Name, string.Format("Creating Log Alert Rule '{0}' in resource group {1}", this.Name, this.ResourceGroupName))) .... 

另一个类似的错误:

  • V3025格式错误。 调用“格式”功能时,期望格式项目的数量不同。 未使用的参数:this.ResourceGroupName。 RemoveScheduledQueryRuleCommand.cs 88(监视器)

V3042可能为NullReferenceException。 '?。' 和“。” 运算符用于访问“ imageAndOsType”对象VirtualMachineScaleSetStrategy.cs 81(计算)的成员

 internal static ResourceConfig<VirtualMachineScaleSet> CreateVirtualMachineScaleSetConfig(...., ImageAndOsType imageAndOsType, ....) { .... VirtualMachineProfile = new VirtualMachineScaleSetVMProfile { OsProfile = new VirtualMachineScaleSetOSProfile { ...., WindowsConfiguration = imageAndOsType.CreateWindowsConfiguration(), // <= ...., }, StorageProfile = new VirtualMachineScaleSetStorageProfile { ImageReference = imageAndOsType?.Image, // <= DataDisks = DataDiskStrategy.CreateVmssDataDisks( imageAndOsType?.DataDiskLuns, dataDisks) // <= }, }, .... } 

创建VirtualMachineScaleSetVMProfile对象时,将对imageAndOsType变量检查是否为空,而不进行任何初步检查。 但是,在创建VirtualMachineScaleSetStorageProfile时 ,甚至已经使用条件访问运算符检查了该变量两次。 该代码看起来并不安全。

V3042可能为NullReferenceException。 '?。' 和“。” 运算符用于访问“ 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(....); // <= } .... } 

在正常执行和处理异常的结果中,变量existingContacts都可以获取值,此后继续执行。 在代码中,此变量的使用没有任何特殊原因。

V3066传递给“ PersistSyncServerRegistration”方法的参数的可能错误顺序:“ storageSyncServiceUid”和“ discoveryUri”。 EcsManagementInteropClient.cs 364(StorageSync)

 public class EcsManagementInteropClient : IEcsManagement { .... public int PersistSyncServerRegistration(....) { return m_managementObject.PersistSyncServerRegistration( serviceUri, subscriptionId, storageSyncServiceName, resourceGroupName, clusterId, clusterName, storageSyncServiceUid, // <= discoveryUri, // <= serviceLocation, resourceLocation); } .... } 

分析器怀疑PersistSyncServerRegistration方法的参数顺序混乱。 方法的声明:

 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, MarshalAs(UnmanagedType.BStr)] string storageSyncServiceUid, // <= [In, MarshalAs(UnmanagedType.BStr)] string serviceLocation, [In, MarshalAs(UnmanagedType.BStr)] string resourceLocation); .... } 

确实,这里的参数7和8有问题。 作者必须检查代码。

V3077 “ GetGuid”属性的设置器未使用其“值”参数。 RecoveryServicesBackupCmdletBase.cs 54(RecoveryServices)

 public abstract class RecoveryServicesBackupCmdletBase : AzureRMCmdlet { .... static string _guid; protected static string GetGuid { get { return _guid; } set { _guid = Guid.NewGuid().ToString(); } } .... } 

设置器不使用传递的参数。 相反,它将创建一个新的GUID并将其分配给_guid字段。 我认为大多数读者都会同意这样的代码看起来至少很难看。 这种构造使用起来不是很方便:当(重新)初始化GetGuid属性时,必须为其分配一个伪值,这不是很明显。 但是最令我吃惊的是作者使用这种模式的方式。 只有一个地方处理GetGuid 。 检查一下:

 public override void ExecuteCmdlet() { .... var itemResponse = ServiceClientAdapter.CreateOrUpdateProtectionIntent( GetGuid ?? Guid.NewGuid().ToString(), ....); .... } 

太棒了!

V3091实证分析。 字符串文字中可能存在拼写错误:“管理组ID”。 “ Id”一词可疑。 Constants.cs 36(资源)

 public class HelpMessages { public const string SubscriptionId = "Subscription Id of the subscription associated with the management"; public const string GroupId = "Management Group Id"; // <= public const string Recurse = "Recursively list the children of the management group"; public const string ParentId = "Parent Id of the management group"; public const string GroupName = "Management Group Id"; // <= public const string DisplayName = "Display Name of the management group"; public const string Expand = "Expand the output to list the children of the management group"; public const string Force = "Force the action and skip confirmations"; public const string InputObject = "Input Object from the Get call"; public const string ParentObject = "Parent Object"; } 

分析器指出GroupName常量的分配字符串中可能存在错误。 该结论基于对其他赋值的实证分析,并考虑了变量名称。 我认为在这种情况下,分析器是正确的,并且GroupName常量的值应该是“管理组名称”的一种。 可能是由于复制了GroupId常量的值但未更改,因此发生了错误。

另一个类似的错误:

  • V3091实证分析。 字符串文字中可能存在错字。 “名称”一词可疑。 ParamHelpMsgs.cs 153(RecoveryServices)

V3093 '|' 运算符同时计算两个操作数。 也许是短路“ ||” 应该使用运算符代替。 PSKeyVaultCertificatePolicy.cs 114(KeyVault)

 internal CertificatePolicy ToCertificatePolicy() { .... if (!string.IsNullOrWhiteSpace(SubjectName) || DnsNames != null || Ekus != null || KeyUsage != null | // <= ValidityInMonths.HasValue) { .... } .... } 

在此片段中可能会发生错误,而在最后两个条件之间的if块中,||可能会发生错误。 可能已经使用了运算符。 但是通常情况下,只有开发人员才能给出正确的答案。

V3095在对null进行验证之前,已使用“证书”对象。 检查行:41,43。CertificateInfo.cs 41(自动化)

 public CertificateInfo( ...., Azure.Management.Automation.Models.Certificate certificate) { .... this.Name = certificate.Name; if (certificate == null) return; .... } 

经典。 首先使用该对象,然后才检查引用是否为null 。 我们经常遇到这样的错误。 让我们考虑另一个类似的错误。

V3095在对null进行验证之前,已使用'clusterCred'对象。 检查行: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) .... } 

这是几个类似的错误:

  • V3095在验证是否为null之前,已使用'_profile'对象。 检查行:47,49。RMProfileClient.cs 47(帐户)
  • V3095在对null进行验证之前,已使用'this.LoadBalancer.BackendAddressPools'对象。 检查行:56,63。AddAzureRmLoadBalancerBackendAddressPoolConfigCommand.cs 56(CognitiveServices)
  • 一般来说,我在Azure PowerShell代码中看到许多V3095错误。 但是它们都非常相似,因此我不会在这个问题上进行介绍。

V3125在验证了null之后使用了“ startTime”对象。 检查行:1752、1738。AutomationPSClientDSC.cs 1752(自动化)

 private string GetNodeReportListFilterString( ...., DateTimeOffset? startTime, ...., DateTimeOffset? lastModifiedTime) { .... if (startTime.HasValue) { odataFilter.Add("properties/startTime ge " + this.FormatDateTime(startTime.Value)); // <= } .... if (lastModifiedTime.HasValue) { odataFilter.Add("properties/lastModifiedTime ge " + this.FormatDateTime(startTime.Value)); // <= } .... } 

这也是相当普遍的错误类型。 首次使用startTime变量时,将检查其是否存在值。 但这并没有在后续使用中完成。 好吧,情况可能更糟。 查看第二个if块。 我认为startTime变量绝对不能在这里。 首先,在使用值之前不检查其值是否存在。 其次,要传递给Add方法的字符串也证实了我的建议。 该字符串的第一部分提到了另一个变量(lastModifiedTime )。

V3125在验证了null之后使用了“ firstPage”对象。 检查行: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)) // <= { .... } .... } 

另一个明显的错误。 尽管在代码的前面已经对该变量进行了初步检查以确保为null ,但仍不安全地使用firstPage变量。

我在Azure PowerShell代码中发现的V3125警告比上述的V3095警告还要多。 它们也都是同一类型。 我认为,我们考虑的其中两个就足够了。

V3137分配了'apiVersionSetId'变量,但未在函数末尾使用。 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)) // <= { WriteObject(....); } else { WriteObject(Client.GetApiVersionSet(...., ApiVersionSetId)) // <= } } 

分析器报告apiVersionSetId局部变量已初始化,但未以任何方式使用。 通常,此模式指示错误。 我认为,在这种情况下,最有可能是一个错误,尤其是考虑到apiVersionSetId局部变量的名称和ApiVersionSetId属性的名称仅在第一个字母的情况下有所不同的事实。 看一下代码。 在初始化apiVersionSetId属性 (以一种或另一种方式)之后,仅ApiVersionSetId属性在代码中进一步使用。 看起来非常可疑。

V3137分配了'cacheId'变量,但在函数末尾未使用该变量。 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); // <= var actionWarning = string.Format(...., CacheId); // <= .... Client.CacheRemove(resourceGroupName, serviceName, CacheId); // <= .... } 

这种情况与前面描述的情况几乎相同。 初始化后,无论如何都不会使用cacheId局部变量。 而是使用另一个名称非常相似的属性CacheId 。 我不确定,可能仅仅是Azure PowerShell开发人员的编程模式。 无论如何,它看起来像一个错误。

V3143 '值'参数在属性设置器中重写,此后不再使用。 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; } // <= } 

使用以下方式声明partnerType字段:

 /// <summary> /// Default partner type. /// </summary> private string partnerType = "B2B"; 

尽管检测到错误的解决方案(LogicApp)的名称,但我在其中找不到逻辑。 在二传手中修改并非罕见,但在这种情况下,它会处理原始值的损失。 看起来很奇怪。 在code属性中只读一次。 也许,我们需要再次寻求专家的建议。 也许我就是不明白。 关键是我遇到了几种相同的模式:

  • V3143'值'参数在属性设置器中重写,此后不再使用。 NewAzureIntegrationAccountSchemaCommand.cs 79(LogicApp)
  • V3143'值'参数在属性设置器中重写,此后不再使用。 NewAzureIntegrationAccountSchemaCommand.cs 87(LogicApp)
  • V3143'值'参数在属性设置器中重写,此后不再使用。 UpdateAzureIntegrationAccountPartnerCommand.cs 67(LogicApp)
  • V3143'值'参数在属性设置器中重写,此后不再使用。 UpdateAzureIntegrationAccountSchemaCommand.cs 80(LogicApp)
  • V3143'值'参数在属性设置器中重写,此后不再使用。 UpdateAzureIntegrationAccountSchemaCommand.cs 88(LogicApp)

结论


这些都是在Azure PowerShell代码中发现的有趣的bug。 欢迎热心者和有兴趣的人自己检查该(或任何其他)项目中的错误。 我可能会错过一些另类的东西。 要进行审核,您只需下载并安装PVS-Studio即可

感谢您的阅读。 而且,当然,没有错误的代码给大家!

Source: https://habr.com/ru/post/zh-CN470728/


All Articles