-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Revert the PRs that made DBNull.Value and NullString.Value treated as $null
#11648
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -593,7 +593,9 @@ public static PSDataCollection<PSObject> GetPSDataCollection(object inputValue) | |
| /// <param name="second">Object to compare first to.</param> | ||
daxian-dbw marked this conversation as resolved.
Show resolved
Hide resolved
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @daxian-dbw, your last commit had 1 failures in Failed to complete request to "https://msdn.microsoft.com/powershell/reference/6/about/about_jobs". Response status code does not indicate success: 404 (Not Found).
at <ScriptBlock>, /home/vsts/work/1/s/test/common/markdown/markdown-link.tests.ps1: line 119
119: throw "Failed to complete request to `"$url`". $($_.Exception.Message)"
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will be addressed by #11653 |
||
| /// <returns>True if first is equal to the second.</returns> | ||
| public static new bool Equals(object first, object second) | ||
| => Equals(first, second, false, CultureInfo.InvariantCulture); | ||
| { | ||
| return Equals(first, second, false, CultureInfo.InvariantCulture); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Used to compare two objects for equality converting the second to the type of the first, if required. | ||
|
|
@@ -604,7 +606,9 @@ public static PSDataCollection<PSObject> GetPSDataCollection(object inputValue) | |
| /// to specify the type of string comparison </param> | ||
| /// <returns>True if first is equal to the second.</returns> | ||
| public static bool Equals(object first, object second, bool ignoreCase) | ||
| => Equals(first, second, ignoreCase, CultureInfo.InvariantCulture); | ||
| { | ||
| return Equals(first, second, ignoreCase, CultureInfo.InvariantCulture); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Used to compare two objects for equality converting the second to the type of the first, if required. | ||
|
|
@@ -642,28 +646,24 @@ public static bool Equals(object first, object second, bool ignoreCase, IFormatP | |
|
|
||
| if (first == null) | ||
| { | ||
| return IsNullLike(second); | ||
| return second == null; | ||
| } | ||
|
|
||
| if (second == null) | ||
| { | ||
| return IsNullLike(first); | ||
| return false; // first is not null | ||
| } | ||
|
|
||
| string firstString = first as string; | ||
| string secondString; | ||
| if (first is string firstString) | ||
| if (firstString != null) | ||
| { | ||
| secondString = second as string ?? (string)LanguagePrimitives.ConvertTo(second, typeof(string), culture); | ||
| return culture.CompareInfo.Compare( | ||
| firstString, | ||
| secondString, | ||
| ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0; | ||
| return (culture.CompareInfo.Compare(firstString, secondString, | ||
| ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0); | ||
| } | ||
|
|
||
| if (first.Equals(second)) | ||
| { | ||
| return true; | ||
| } | ||
| if (first.Equals(second)) return true; | ||
|
|
||
| Type firstType = first.GetType(); | ||
| Type secondType = second.GetType(); | ||
|
|
@@ -707,24 +707,24 @@ public static bool Equals(object first, object second, bool ignoreCase, IFormatP | |
| /// Helper method for [Try]Compare to determine object ordering with null. | ||
| /// </summary> | ||
| /// <param name="value">The numeric value to compare to null.</param> | ||
| /// <param name="numberIsRightHandSide">True if the number to compare is on the right hand side in the comparison.</param> | ||
| /// <param name="numberIsRightHandSide">True if the number to compare is on the right hand side if the comparison.</param> | ||
| private static int CompareObjectToNull(object value, bool numberIsRightHandSide) | ||
| { | ||
| var i = numberIsRightHandSide ? -1 : 1; | ||
|
|
||
| // If it's a positive number, including 0, it's greater than null | ||
| // for everything else it's less than zero... | ||
| return value switch | ||
| { | ||
| Int16 i16 => Math.Sign(i16) < 0 ? -i : i, | ||
| Int32 i32 => Math.Sign(i32) < 0 ? -i : i, | ||
| Int64 i64 => Math.Sign(i64) < 0 ? -i : i, | ||
| sbyte s => Math.Sign(s) < 0 ? -i : i, | ||
| float f => Math.Sign(f) < 0 ? -i : i, | ||
| double d => Math.Sign(d) < 0 ? -i : i, | ||
| decimal m => Math.Sign(m) < 0 ? -i : i, | ||
| _ => IsNullLike(value) ? 0 : i | ||
| }; | ||
| switch (value) | ||
| { | ||
| case Int16 i16: return Math.Sign(i16) < 0 ? -i : i; | ||
| case Int32 i32: return Math.Sign(i32) < 0 ? -i : i; | ||
| case Int64 i64: return Math.Sign(i64) < 0 ? -i : i; | ||
| case sbyte sby: return Math.Sign(sby) < 0 ? -i : i; | ||
| case float f: return Math.Sign(f) < 0 ? -i : i; | ||
| case double d: return Math.Sign(d) < 0 ? -i : i; | ||
| case decimal de: return Math.Sign(de) < 0 ? -i : i; | ||
| default: return i; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
|
|
@@ -740,7 +740,9 @@ private static int CompareObjectToNull(object value, bool numberIsRightHandSide) | |
| /// to the type of <paramref name="first"/>. | ||
| /// </exception> | ||
| public static int Compare(object first, object second) | ||
| => LanguagePrimitives.Compare(first, second, false, CultureInfo.InvariantCulture); | ||
| { | ||
| return LanguagePrimitives.Compare(first, second, false, CultureInfo.InvariantCulture); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Compare first and second, converting second to the | ||
|
|
@@ -756,7 +758,9 @@ public static int Compare(object first, object second) | |
| /// to the type of <paramref name="first"/>. | ||
| /// </exception> | ||
| public static int Compare(object first, object second, bool ignoreCase) | ||
| => LanguagePrimitives.Compare(first, second, ignoreCase, CultureInfo.InvariantCulture); | ||
| { | ||
| return LanguagePrimitives.Compare(first, second, ignoreCase, CultureInfo.InvariantCulture); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Compare first and second, converting second to the | ||
|
|
@@ -774,20 +778,23 @@ public static int Compare(object first, object second, bool ignoreCase) | |
| /// </exception> | ||
| public static int Compare(object first, object second, bool ignoreCase, IFormatProvider formatProvider) | ||
| { | ||
| formatProvider ??= CultureInfo.InvariantCulture; | ||
| if (formatProvider == null) | ||
| { | ||
| formatProvider = CultureInfo.InvariantCulture; | ||
| } | ||
|
|
||
| var culture = formatProvider as CultureInfo; | ||
| if (culture == null) | ||
| { | ||
| throw PSTraceSource.NewArgumentException(nameof(formatProvider)); | ||
| throw PSTraceSource.NewArgumentException("formatProvider"); | ||
| } | ||
|
|
||
| first = PSObject.Base(first); | ||
| second = PSObject.Base(second); | ||
|
|
||
| if (first == null) | ||
| { | ||
| return CompareObjectToNull(second, true); | ||
| return second == null ? 0 : CompareObjectToNull(second, true); | ||
| } | ||
|
|
||
| if (second == null) | ||
|
|
@@ -797,7 +804,7 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP | |
|
|
||
| if (first is string firstString) | ||
| { | ||
| var secondString = second as string; | ||
| string secondString = second as string; | ||
| if (secondString == null) | ||
| { | ||
| try | ||
|
|
@@ -806,26 +813,19 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP | |
| } | ||
| catch (PSInvalidCastException e) | ||
| { | ||
| throw PSTraceSource.NewArgumentException( | ||
| nameof(second), | ||
| ExtendedTypeSystem.ComparisonFailure, | ||
| first.ToString(), | ||
| second.ToString(), | ||
| e.Message); | ||
| throw PSTraceSource.NewArgumentException("second", ExtendedTypeSystem.ComparisonFailure, | ||
| first.ToString(), second.ToString(), e.Message); | ||
| } | ||
| } | ||
|
|
||
| return culture.CompareInfo.Compare( | ||
| firstString, | ||
| secondString, | ||
| ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); | ||
| return culture.CompareInfo.Compare(firstString, secondString, | ||
| ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); | ||
| } | ||
|
|
||
| Type firstType = first.GetType(); | ||
| Type secondType = second.GetType(); | ||
| int firstIndex = LanguagePrimitives.TypeTableIndex(firstType); | ||
| int secondIndex = LanguagePrimitives.TypeTableIndex(secondType); | ||
|
|
||
| if ((firstIndex != -1) && (secondIndex != -1)) | ||
| { | ||
| return LanguagePrimitives.NumericCompare(first, second, firstIndex, secondIndex); | ||
|
|
@@ -838,12 +838,8 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP | |
| } | ||
| catch (PSInvalidCastException e) | ||
| { | ||
| throw PSTraceSource.NewArgumentException( | ||
| nameof(second), | ||
| ExtendedTypeSystem.ComparisonFailure, | ||
| first.ToString(), | ||
| second.ToString(), | ||
| e.Message); | ||
| throw PSTraceSource.NewArgumentException("second", ExtendedTypeSystem.ComparisonFailure, | ||
| first.ToString(), second.ToString(), e.Message); | ||
| } | ||
|
|
||
| if (first is IComparable firstComparable) | ||
|
|
@@ -858,7 +854,7 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP | |
|
|
||
| // At this point, we know that they aren't equal but we have no way of | ||
| // knowing which should compare greater than the other so we throw an exception. | ||
| throw PSTraceSource.NewArgumentException(nameof(first), ExtendedTypeSystem.NotIcomparable, first.ToString()); | ||
| throw PSTraceSource.NewArgumentException("first", ExtendedTypeSystem.NotIcomparable, first.ToString()); | ||
| } | ||
|
|
||
| /// <summary> | ||
|
|
@@ -871,7 +867,9 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP | |
| /// zero if it is greater or zero if they are the same.</param> | ||
| /// <returns>True if the comparison was successful, false otherwise.</returns> | ||
| public static bool TryCompare(object first, object second, out int result) | ||
| => TryCompare(first, second, ignoreCase: false, CultureInfo.InvariantCulture, out result); | ||
| { | ||
| return TryCompare(first, second, ignoreCase: false, CultureInfo.InvariantCulture, out result); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Tries to compare first and second, converting second to the type of the first, if necessary. | ||
|
|
@@ -883,7 +881,9 @@ public static bool TryCompare(object first, object second, out int result) | |
| /// <param name="result">Less than zero if first is smaller than second, more than zero if it is greater or zero if they are the same.</param> | ||
| /// <returns>True if the comparison was successful, false otherwise.</returns> | ||
| public static bool TryCompare(object first, object second, bool ignoreCase, out int result) | ||
| => TryCompare(first, second, ignoreCase, CultureInfo.InvariantCulture, out result); | ||
| { | ||
| return TryCompare(first, second, ignoreCase, CultureInfo.InvariantCulture, out result); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Tries to compare first and second, converting second to the type of the first, if necessary. | ||
|
|
@@ -899,7 +899,10 @@ public static bool TryCompare(object first, object second, bool ignoreCase, out | |
| public static bool TryCompare(object first, object second, bool ignoreCase, IFormatProvider formatProvider, out int result) | ||
| { | ||
| result = 0; | ||
| formatProvider ??= CultureInfo.InvariantCulture; | ||
| if (formatProvider == null) | ||
| { | ||
| formatProvider = CultureInfo.InvariantCulture; | ||
| } | ||
|
|
||
| if (!(formatProvider is CultureInfo culture)) | ||
| { | ||
|
|
@@ -984,10 +987,8 @@ public static bool TryCompare(object first, object second, bool ignoreCase, IFor | |
| public static bool IsTrue(object obj) | ||
| { | ||
| // null is a valid argument - it converts to false... | ||
| if (IsNullLike(obj)) | ||
| { | ||
| if (obj == null || obj == AutomationNull.Value) | ||
| return false; | ||
| } | ||
|
|
||
| obj = PSObject.Base(obj); | ||
|
|
||
|
|
@@ -1013,7 +1014,8 @@ public static bool IsTrue(object obj) | |
| if (objType == typeof(SwitchParameter)) | ||
| return ((SwitchParameter)obj).ToBool(); | ||
|
|
||
| if (obj is IList objectArray) | ||
| IList objectArray = obj as IList; | ||
| if (objectArray != null) | ||
| { | ||
| return IsTrue(objectArray); | ||
| } | ||
|
|
@@ -1058,20 +1060,15 @@ internal static bool IsTrue(IList objectArray) | |
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Internal routine that determines if an object meets any of our criteria for true null. | ||
| /// </summary> | ||
| /// <param name="obj">The object to test.</param> | ||
| /// <returns>True if the object is null.</returns> | ||
| public static bool IsNull(object obj) => obj == null || obj == AutomationNull.Value; | ||
|
|
||
| /// <summary> | ||
| /// Internal routine that determines if an object meets any of our criteria for null. | ||
| /// This method additionally checks for <see cref="NullString.Value"/> and <see cref="DBNull.Value"/> | ||
| /// </summary> | ||
| /// <param name="obj">The object to test.</param> | ||
| /// <returns>True if the object is null.</returns> | ||
| public static bool IsNullLike(object obj) => IsNull(obj) || obj == DBNull.Value || obj == NullString.Value; | ||
| internal static bool IsNull(object obj) | ||
| { | ||
| return (obj == null || obj == AutomationNull.Value); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Auxiliary for the cases where we want a new PSObject or null. | ||
|
|
@@ -3086,17 +3083,15 @@ private static object ConvertToVoid(object valueToConvert, | |
| return AutomationNull.Value; | ||
| } | ||
|
|
||
| private static bool ConvertClassToBool( | ||
| object valueToConvert, | ||
| Type resultType, | ||
| bool recursion, | ||
| PSObject originalValueToConvert, | ||
| IFormatProvider formatProvider, | ||
| TypeTable backupTable) | ||
| private static bool ConvertClassToBool(object valueToConvert, | ||
| Type resultType, | ||
| bool recursion, | ||
| PSObject originalValueToConvert, | ||
| IFormatProvider formatProvider, | ||
| TypeTable backupTable) | ||
| { | ||
| typeConversion.WriteLine("Converting ref to boolean."); | ||
| // Both NullString and DBNull should be treated the same as true nulls for the purposes of this conversion. | ||
| return !IsNullLike(valueToConvert); | ||
| return valueToConvert != null; | ||
| } | ||
|
|
||
| private static bool ConvertValueToBool(object valueToConvert, | ||
|
|
@@ -4712,11 +4707,10 @@ internal static IConversionData FigureConversion(object valueToConvert, Type res | |
| { | ||
| PSObject valueAsPsObj; | ||
| Type originalType; | ||
|
|
||
| if (IsNull(valueToConvert)) | ||
| if (valueToConvert == null || valueToConvert == AutomationNull.Value) | ||
| { | ||
| originalType = typeof(Null); | ||
| valueAsPsObj = null; | ||
| originalType = typeof(Null); | ||
| } | ||
| else | ||
| { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.