0

I was playing around with the SslPolicyErrors enum and noticed the following behavior:

SslPolicyErrors error = SslPolicyErrors.RemoteCertificateChainErrors
                      | SslPolicyErrors.None
                      | SslPolicyErrors.RemoteCertificateNameMismatch;

Console.WriteLine(error.HasFlag(SslPolicyErrors.None));
Console.WriteLine(error.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors));
Console.WriteLine(error.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch));

I would expect the first print for the None flag to be false, but to my surprise all three prints were true:

True
True
True

So I looked up the source and found this:

    [Flags]
    public enum SslPolicyErrors
    {
        None                          = 0x0,
        RemoteCertificateNotAvailable = 0x1,
        RemoteCertificateNameMismatch = 0x2,
        RemoteCertificateChainErrors  = 0x4
    }

Which was exactly what I expected initially, but I don't understand how an instance can both have the None flag and at the same time one or more other flags.

Jurgy
  • 2,128
  • 1
  • 20
  • 33
  • 1
    `0 & 0 == 0` checks out. – ProgrammingLlama Apr 12 '23 at 08:05
  • 1
    @YongShun, the article doesn't go into the specifics of the zero flag. @ProgrammingLlama, I understand that that is what the underlying check does. But How could the check `if (sslPolicyErrors == SslPolicyErrors.None)` ever be safe? (From the ms docs: https://learn.microsoft.com/en-us/dotnet/api/system.net.security.remotecertificatevalidationcallback?view=net-7.0) – Jurgy Apr 12 '23 at 08:10
  • 3
    `sslPolicyErrors == SslPolicyErrors.None` isn't the same check as `error.HasFlag(SslPolicyErrors.None)`. The equality check will only return `true` if it is exactly equal to 0, whereas the `HasFlag` check will always return `true` for `None`. – ProgrammingLlama Apr 12 '23 at 08:12
  • @Jurgy HasFlag checks for one flag, checking for equality to zero checks that no (non-zero) flags are set. – Andrew Morton Apr 12 '23 at 08:12
  • 1
    Oh right, looked right over that. Of course! Thanks. – Jurgy Apr 12 '23 at 08:13

1 Answers1

2

Question was answered in the comments but for completeness sake I will answer it myself.

From the docs itself:

The HasFlag method returns the result of the following Boolean expression.

thisInstance And flag = flag

If the underlying value of flag is zero, the method returns true. If this behavior is not desirable, you can use the Equals method to test for equality with zero and call HasFlag only if the underlying value of flag is non-zero, as the following example illustrates.

So for zero flags you have to do flag == Flags.None instead of flag.HasFlag(Flags.None)

Jurgy
  • 2,128
  • 1
  • 20
  • 33