Repository: PowerShell/PowerShell
File: src/System.Management.Automation/engine/LanguagePrimitives.cs (C#)

Code before:
                                    PSObject originalValueToConvert,
                                    IFormatProvider formatProvider,
                                    TypeTable backupTable)
            {
                return Convert(valueToConvert, resultType, recursion, originalValueToConvert, formatProvider, backupTable, false);
            }

            internal object Convert(object valueToConvert,
                        Type resultType,
                        bool recursion,
                        PSObject originalValueToConvert,
                        IFormatProvider formatProvider,
                        TypeTable backupTable, bool ignoreUnknownMembers)
            {
                try
                {
                    ExecutionContext ecFromTLS = LocalPipeline.GetExecutionContextFromTLS();
                    object result = null;

                    // Setting arbitrary properties is dangerous, so we allow this only if
                    //  - It's running on a thread without Runspace; Or
                    //  - It's in FullLanguage but not because it's part of a parameter binding that is transitioning from ConstrainedLanguage to FullLanguage
                    // When this is invoked from a parameter binding in transition from ConstrainedLanguage environment to FullLanguage command, we disallow
                    // the property conversion because it's dangerous.
                    bool canProceedWithConversion = ecFromTLS == null || (ecFromTLS.LanguageMode == PSLanguageMode.FullLanguage && !ecFromTLS.LanguageModeTransitionInParameterBinding);
                    if (!canProceedWithConversion)
                    {
                        if (SystemPolicy.GetSystemLockdownPolicy() == SystemEnforcementMode.Audit)
                        {
                            SystemPolicy.LogWDACAuditMessage(
                                context: ecFromTLS,
                                title: ExtendedTypeSystem.WDACHashTypeLogTitle,
                                message: StringUtil.Format(ExtendedTypeSystem.WDACHashTypeLogMessage, resultType.FullName),
                                fqid: "LanguageHashtableConversionNotAllowed",
                                dropIntoDebugger: true);
                        }
                        else
                        {
                            RuntimeException rte = InterpreterError.NewInterpreterException(valueToConvert, typeof(RuntimeException), null,
                                "HashtableToObjectConversionNotSupportedInDataSection", ParserStrings.HashtableToObjectConversionNotSupportedInDataSection, resultType.ToString());
                            throw rte;
                        }
                    }

                    result = _constructor();
                    var psobject = valueToConvert as PSObject;
                    if (psobject != null)
                    {
                        // Use PSObject properties to perform conversion.
                        SetObjectProperties(result, psobject, resultType, CreateMemberNotFoundError, CreateMemberSetValueError, formatProvider, recursion, ignoreUnknownMembers);
                    }

Review comment (suggestion):
is there also a problem with the if/else in (now) 4010/4019. I thought that the audit mode was to _not_ change the behavior, and just log. However, if audit mode is enabled, then the exception 4021 will _not_ be thrown. It seemed to me that the `else` was an oversight and the throw should occur whether we're auditing or not.

Code after:
                                    PSObject originalValueToConvert,
                                    IFormatProvider formatProvider,
                                    TypeTable backupTable)
            {
                return Convert(valueToConvert, resultType, recursion, originalValueToConvert, formatProvider, backupTable, false);
            }

            internal object Convert(object valueToConvert,
                        Type resultType,
                        bool recursion,
                        PSObject originalValueToConvert,
                        IFormatProvider formatProvider,
                        TypeTable backupTable, bool ignoreUnknownMembers)
            {
                try
                {
                    ExecutionContext ecFromTLS = LocalPipeline.GetExecutionContextFromTLS();
                    object result = null;

                    // Setting arbitrary properties is dangerous, so we allow this only if
                    //  - It's running on a thread without Runspace; Or
                    //  - It's in FullLanguage but not because it's part of a parameter binding that is transitioning from ConstrainedLanguage to FullLanguage
                    // When this is invoked from a parameter binding in transition from ConstrainedLanguage environment to FullLanguage command, we disallow
                    // the property conversion because it's dangerous.
                    bool canProceedWithConversion = ecFromTLS == null || (ecFromTLS.LanguageMode == PSLanguageMode.FullLanguage && !ecFromTLS.LanguageModeTransitionInParameterBinding);
                    if (!canProceedWithConversion)
                    {
                        if (SystemPolicy.GetSystemLockdownPolicy() != SystemEnforcementMode.Audit)
                        {
                            throw InterpreterError.NewInterpreterException(
                                valueToConvert,
                                typeof(RuntimeException),
                                errorPosition: null,
                                "HashtableToObjectConversionNotSupportedInDataSection",
                                ParserStrings.HashtableToObjectConversionNotSupportedInDataSection,
                                resultType.ToString());
                        }

                        // When in audit mode, we report but don't enforce, so we will proceed with the conversion.
                        SystemPolicy.LogWDACAuditMessage(
                                context: ecFromTLS,
                                title: ExtendedTypeSystem.WDACHashTypeLogTitle,
                                message: StringUtil.Format(ExtendedTypeSystem.WDACHashTypeLogMessage, resultType.FullName),
                                fqid: "LanguageHashtableConversionNotAllowed",
                                dropIntoDebugger: true);
                    }

                    result = _constructor();
                    var psobject = valueToConvert as PSObject;
                    if (psobject != null)
                    {