From b09eb33e0a79337326fec26574577fac9033b6cc Mon Sep 17 00:00:00 2001 From: "Christoph Bergmeister [MVP]" Date: Wed, 12 Jun 2019 02:31:25 +0100 Subject: [PATCH] Lock calls around Test-ModuleManifest, which is not thread safe (#1258) --- Engine/Helper.cs | 55 ++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 5af3a9fcf..330547d02 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -31,6 +31,7 @@ public class Helper private readonly Lazy _commandInfoCacheLazy; private readonly RunspacePool _runSpacePool; + private readonly object _testModuleManifestLock = new object(); #endregion @@ -303,35 +304,39 @@ public PSModuleInfo GetModuleManifest(string filePath, out IEnumerable psObj = null; - using (var ps = System.Management.Automation.PowerShell.Create()) + // Test-ModuleManifest is not thread safe + lock (_testModuleManifestLock) { - ps.RunspacePool = _runSpacePool; - ps.AddCommand("Test-ModuleManifest") - .AddParameter("Path", filePath) - .AddParameter("WarningAction", ActionPreference.SilentlyContinue); - try + using (var ps = System.Management.Automation.PowerShell.Create()) { - psObj = ps.Invoke(); - } - catch (CmdletInvocationException e) - { - // Invoking Test-ModuleManifest on a module manifest that doesn't have all the valid keys - // throws a NullReferenceException. This is probably a bug in Test-ModuleManifest and hence - // we consume it to allow execution of the of this method. - if (e.InnerException == null || e.InnerException.GetType() != typeof(System.NullReferenceException)) + ps.RunspacePool = _runSpacePool; + ps.AddCommand("Test-ModuleManifest") + .AddParameter("Path", filePath) + .AddParameter("WarningAction", ActionPreference.SilentlyContinue); + try { - throw; + psObj = ps.Invoke(); + } + catch (CmdletInvocationException e) + { + // Invoking Test-ModuleManifest on a module manifest that doesn't have all the valid keys + // throws a NullReferenceException. This is probably a bug in Test-ModuleManifest and hence + // we consume it to allow execution of the of this method. + if (e.InnerException == null || e.InnerException.GetType() != typeof(System.NullReferenceException)) + { + throw; + } + } + if (ps.HadErrors && ps.Streams != null && ps.Streams.Error != null) + { + var errorRecordArr = new ErrorRecord[ps.Streams.Error.Count]; + ps.Streams.Error.CopyTo(errorRecordArr, 0); + errorRecord = errorRecordArr; + } + if (psObj != null && psObj.Any() && psObj[0] != null) + { + psModuleInfo = psObj[0].ImmediateBaseObject as PSModuleInfo; } - } - if (ps.HadErrors && ps.Streams != null && ps.Streams.Error != null) - { - var errorRecordArr = new ErrorRecord[ps.Streams.Error.Count]; - ps.Streams.Error.CopyTo(errorRecordArr, 0); - errorRecord = errorRecordArr; - } - if (psObj != null && psObj.Any() && psObj[0] != null) - { - psModuleInfo = psObj[0].ImmediateBaseObject as PSModuleInfo; } } return psModuleInfo;