Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is this C idiom (if (1))?

I noticed a strange idiom in openssl source code, here and repeated below:

if ((in == NULL) && (passwds == NULL)) {
        if (1) {                                    (* <---- HERE *)
#ifndef OPENSSL_NO_UI
            /* build a null-terminated list */
            static char *passwds_static[2] = { NULL, NULL };

            passwds = passwds_static;
            if (in == NULL)
                if (EVP_read_pw_string
                    (passwd_malloc, passwd_malloc_size, "Password: ",
                     !(passed_salt || in_noverify)) != 0)
                    goto end;
            passwds[0] = passwd_malloc;
        } else {
#endif
            BIO_printf(bio_err, "password required\n");
            goto end;
        }
}

It seems that this piece of code is equivalent to:

if ((in == NULL) && (passwds == NULL)) {
#ifndef OPENSSL_NO_UI
        /* build a null-terminated list */
        static char *passwds_static[2] = { NULL, NULL };

        passwds = passwds_static;
        if (in == NULL)
            if (EVP_read_pw_string
                (passwd_malloc, passwd_malloc_size, "Password: ",
                 !(passed_salt || in_noverify)) != 0)
                goto end;
        passwds[0] = passwd_malloc;
#else
        BIO_printf(bio_err, "password required\n");
        goto end;
#endif
}

I ruled out some explanations:

  • it could be to introduce block scope for passwds_static, but the enclosing if would serve a similar purpose
  • it could be a construct that through several meaningful transformations becomes meaningless, but that construct is there since the introduction of OPENSSL_NO_UI.

Am I missing something here? What are the advantages of this if (1)? Is this used in other code bases?

Thanks!

like image 922
Étienne Millon Avatar asked Mar 28 '17 08:03

Étienne Millon


Video Answer


1 Answers

After looking at other similar places, I found an explanation:

if (1) { /* This is a trick we use to avoid bit rot.
          * at least the "else" part will always be
          * compiled.
          */
#ifdef AF_INET6
    family = AF_INET6;
} else {
#endif
    BIOerr(BIO_F_ACPT_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
    goto exit_loop;
}

In most cases (including their CI I guess), OPENSSL_NO_UI is not defined, so both branches are compiled. If the API one of the branches uses changes, it will be spotted by the compiler, and it can be fixed, without having to test all the compile-time switches.

like image 184
Étienne Millon Avatar answered Oct 11 '22 18:10

Étienne Millon