Skip to content
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

A name resolution problem about EVP_PKEY_id #1975

Closed
bvanjoi opened this issue Jun 22, 2023 · 1 comment · Fixed by #1976
Closed

A name resolution problem about EVP_PKEY_id #1975

bvanjoi opened this issue Jun 22, 2023 · 1 comment · Fixed by #1976

Comments

@bvanjoi
Copy link

bvanjoi commented Jun 22, 2023

Background

We were attempting to fix a name resolution bug in rustc on rust-lang/rust#112743. During our regression testing, we discovered an issue with rust-openssl. In this post, I'll describe the bug and explore potential solutions.

Error log

[INFO] [stderr]    Compiling openssl-macros v0.1.1
[INFO] [stdout] error[E0425]: cannot find function, tuple struct or tuple variant `EVP_PKEY_id` in crate `ffi`
[INFO] [stdout]    --> src/pkey.rs:195:36
[INFO] [stdout]     |
[INFO] [stdout] 195 |         unsafe { Id::from_raw(ffi::EVP_PKEY_id(self.as_ptr())) }
[INFO] [stdout]     |                                    ^^^^^^^^^^^ help: a constant with a similar name exists: `EVP_PKEY_DH`
[INFO] [stdout]     |
[INFO] [stdout]    ::: /opt/rustwide/cargo-home/registry/src/index.crates.io-6f17d22bba15001f/openssl-sys-0.9.88/src/./evp.rs:11:1
[INFO] [stdout]     |
[INFO] [stdout] 11  | pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement;
[INFO] [stdout]     | ---------------------------- similarly named constant `EVP_PKEY_DH` defined here

More details: rust-lang/rust#112743 (comment)

Reduced

macro_rules! cfg_if {
  ($(
      if #[cfg($($meta:meta),*)] { $($it:item)* }
  ) else * else {
      $($it2:item)*
  }) => {
      cfg_if! {
          @__items
          () ;
          $( ( ($($meta),*) ($($it)*) ), )*
          ( () ($($it2)*) ),
      }
  };

  (
      if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
      $(
          else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
      )*
  ) => {
      cfg_if! {
          @__items
          () ;
          ( ($($i_met),*) ($($i_it)*) ),
          $( ( ($($e_met),*) ($($e_it)*) ), )*
          ( () () ),
      }
  };

  (@__items ($($not:meta,)*) ; ) => {};
  (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
      cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }

      cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
  };

  (@__apply $m:meta, $($it:item)*) => {
      $(#[$m] $it)*
  };
}

mod openssl {
    pub use self::evp::*;
    pub use self::handwritten::*;

    mod evp {
        cfg_if! {
            if #[cfg(ossl300)] {
                pub unsafe fn EVP_PKEY_id() {}
            }
        }
    }

    mod handwritten {
        pub use self::evp::*;

        mod evp {
            cfg_if! {
                if #[cfg(ossl300)]  {
                    pub unsafe fn EVP_PKEY_id() {}
                } else {
                    extern "C" {
                        pub fn EVP_PKEY_id();
                    }
                }
            }
        }
    }
}

pub use openssl::*;

fn main() {
    unsafe {
        EVP_PKEY_id();
    }
}

Actually, when we compile using rustc code.rs --cfg ossl300, we expect to see an ambiguous error related to EVP_PKEY_id. However, this error is not currently being thrown. Instead, the result indicates that EVP_PKEY_id is referring to openssl::evp::EVP_PKEY_id.

btw, if you remove the cfg_if, you will encounter an ambiguous error:

mod openssl {
    pub use self::evp::*;
    pub use self::handwritten::*;

    mod evp {
        #[cfg(all(ossl300, not(any())))]
        pub unsafe fn EVP_PKEY_id() {}
    }

    mod handwritten {
        pub use self::evp::*;

        mod evp {
            #[cfg(all(ossl300, not(any())))]
            pub unsafe fn EVP_PKEY_id() {}

            #[cfg(all(not(any(ossl300))))]
            extern "C" {
                pub fn EVP_PKEY_id();
            }
        }
    }
}
pub use openssl::*;

fn main() {
    unsafe {
        EVP_PKEY_id(); //  `EVP_PKEY_id` is ambiguous
    }
}

Expected

Since I'm not familiar with this project, I'm not entirely certain how to fix this issue correctly. One possible solution is to remove the pub keyword from pub unsafe fn EVP_PKEY_id() {} in handwritten::evp, or to rename it. In any case, I believe we can resolve this problem and release a new version once it's fixed.

@sfackler
Copy link
Owner

Ah yeah we should remove the versions in handwritten/evp.rs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants