Unverified Commit f958176b authored by Steven Fackler's avatar Steven Fackler Committed by GitHub
Browse files

Merge pull request #1359 from stbuehler/const-ptr-api-macro

Add and use const_ptr_api macro in openssl-sys
parents e796b76e 1dbeb8cb
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -61,14 +61,8 @@ extern "C" {
    pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
}

cfg_if! {
    if #[cfg(any(ossl110, libressl280))] {
const_ptr_api! {
    extern "C" {
            pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *const ASN1_STRING) -> c_int;
        }
    } else {
        extern "C" {
            pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *mut ASN1_STRING) -> c_int;
        }
        pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: #[const_ptr_if(any(ossl110, libressl280))] ASN1_STRING) -> c_int;
    }
}
+8 −31
Original line number Diff line number Diff line
@@ -60,17 +60,10 @@ pub unsafe fn BIO_get_mem_data(b: *mut BIO, pp: *mut *mut c_char) -> c_long {
    BIO_ctrl(b, BIO_CTRL_INFO, 0, pp as *mut c_void)
}

cfg_if! {
    if #[cfg(any(ossl110, libressl280))] {
        extern "C" {
            pub fn BIO_s_file() -> *const BIO_METHOD;
            pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO;
        }
    } else {
const_ptr_api! {
    extern "C" {
            pub fn BIO_s_file() -> *mut BIO_METHOD;
            pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
        }
        pub fn BIO_s_file() -> #[const_ptr_if(any(ossl110, libressl280))] BIO_METHOD;
        pub fn BIO_new(type_: #[const_ptr_if(any(ossl110, libressl280))] BIO_METHOD) -> *mut BIO;
    }
}
extern "C" {
@@ -88,26 +81,10 @@ extern "C" {
    pub fn BIO_free_all(b: *mut BIO);
}

cfg_if! {
    if #[cfg(any(ossl110, libressl280))] {
        extern "C" {
            pub fn BIO_s_mem() -> *const BIO_METHOD;
        }
    } else {
        extern "C" {
            pub fn BIO_s_mem() -> *mut BIO_METHOD;
        }
    }
}
cfg_if! {
    if #[cfg(any(ossl102, libressl280))] {
const_ptr_api! {
    extern "C" {
            pub fn BIO_new_mem_buf(buf: *const c_void, len: c_int) -> *mut BIO;
        }
    } else {
        extern "C" {
            pub fn BIO_new_mem_buf(buf: *mut c_void, len: c_int) -> *mut BIO;
        }
        pub fn BIO_s_mem() -> #[const_ptr_if(any(ossl110, libressl280))] BIO_METHOD;
        pub fn BIO_new_mem_buf(buf: #[const_ptr_if(any(ossl102, libressl280))] c_void, len: c_int) -> *mut BIO;
    }
}

+16 −44
Original line number Diff line number Diff line
@@ -174,15 +174,9 @@ extern "C" {
        outl: *mut c_int,
    ) -> c_int;
}
cfg_if! {
    if #[cfg(any(ossl111b, libressl280))] {
        extern "C" {
            pub fn EVP_PKEY_size(pkey: *const EVP_PKEY) -> c_int;
        }
    } else {
const_ptr_api! {
    extern "C" {
            pub fn EVP_PKEY_size(pkey: *mut EVP_PKEY) -> c_int;
        }
        pub fn EVP_PKEY_size(pkey: #[const_ptr_if(any(ossl111b, libressl280))] EVP_PKEY) -> c_int;
    }
}
cfg_if! {
@@ -206,25 +200,15 @@ cfg_if! {
        }
    }
}
cfg_if! {
    if #[cfg(any(ossl102, libressl280))] {
        extern "C" {
            pub fn EVP_DigestVerifyFinal(
                ctx: *mut EVP_MD_CTX,
                sigret: *const c_uchar,
                siglen: size_t,
            ) -> c_int;
        }
    } else {
const_ptr_api! {
    extern "C" {
        pub fn EVP_DigestVerifyFinal(
            ctx: *mut EVP_MD_CTX,
                sigret: *mut c_uchar,
            sigret: #[const_ptr_if(any(ossl102, libressl280))] c_uchar,
            siglen: size_t,
        ) -> c_int;
    }
}
}

extern "C" {
    pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX;
@@ -317,15 +301,9 @@ extern "C" {

    pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int;
}
cfg_if! {
    if #[cfg(any(ossl110, libressl280))] {
        extern "C" {
            pub fn EVP_PKEY_bits(key: *const EVP_PKEY) -> c_int;
        }
    } else {
const_ptr_api! {
    extern "C" {
            pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;
        }
        pub fn EVP_PKEY_bits(key: #[const_ptr_if(any(ossl110, libressl280))] EVP_PKEY) -> c_int;
    }
}
extern "C" {
@@ -456,15 +434,9 @@ extern "C" {
    ) -> c_int;
}

cfg_if! {
    if #[cfg(any(ossl110, libressl280))] {
        extern "C" {
            pub fn EVP_PKCS82PKEY(p8: *const PKCS8_PRIV_KEY_INFO) -> *mut EVP_PKEY;
        }
    } else {
const_ptr_api! {
    extern "C" {
            pub fn EVP_PKCS82PKEY(p8: *mut PKCS8_PRIV_KEY_INFO) -> *mut EVP_PKEY;
        }
        pub fn EVP_PKCS82PKEY(p8: #[const_ptr_if(any(ossl110, libressl280))] PKCS8_PRIV_KEY_INFO) -> *mut EVP_PKEY;
    }
}

+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
    unused_imports
)]
#![doc(html_root_url = "https://docs.rs/openssl-sys/0.9")]
#![recursion_limit = "128"] // configure fixed limit across all rust versions

extern crate libc;

+209 −0
Original line number Diff line number Diff line
@@ -85,3 +85,212 @@ macro_rules! const_fn {
        )*
    }
}

// openssl changes `*mut` to `*const` in certain parameters in certain versions;
// in C this is ABI and (mostly) API compatible.
//
// We need to handle this explicitly, and this macro helps annotate which
// parameter got converted in which version.
//
// Input is:
//    extern "C" {
//        #[attributes...]
//        pub fn name(args) -> rettype; // `-> rettype` optional
//        // more functions...
//    }
//
// This macro replaces `#[const_ptr_if(...)]` in types with `*const` or `*mut`
// (depending on the inner cfg flags)
//
// Walks through all argument and return types, but only finds inner types of
// `*const` and `*mut`; doesn't walk arrays or generics.
//
// NOTE: can't abstract `pub` as `$fn_vis:vis`, as ctest macro handling doesn't
// support it (old syntax crate). But we really only need `pub` anyway.
//
// NOTE: ctest seams to simply ignore macros it can't expand (whatever the
// reason)
macro_rules! const_ptr_api {
    // ----------------------------------------------------------------
    // (partialarg): partial argument, waiting for "final" argument type
    // MAGIC PART 1: hande conditional const ptr in argument type
    ( (partialarg)
        { $(#[$fn_attr:meta])* pub fn $fn_name:ident }
        $args_packed:tt
        [ $($part_arg:tt)* ]
        [ #[const_ptr_if( $($cfg:tt)* )] $($arg_rem:tt)* ]
        $ret_packed:tt
    ) => {
        const_ptr_api!( (partialarg) { #[cfg($($cfg)*)]      $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_arg)* *const ] [ $($arg_rem)* ] $ret_packed );
        const_ptr_api!( (partialarg) { #[cfg(not($($cfg)*))] $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_arg)* *mut   ] [ $($arg_rem)* ] $ret_packed );
    };
    // continue partial argument with `*mut` pointer (might need special const handling in inner type)
    ( (partialarg)
        $def_packed:tt
        $args_packed:tt
        [ $($part_arg:tt)* ]
        [ *mut $($arg_rem:tt)* ]
        $ret_packed:tt
    ) => {
        const_ptr_api!( (partialarg) $def_packed $args_packed [ $($part_arg)* *mut ] [ $($arg_rem)* ] $ret_packed );
    };
    // continue partial argument with `*const` pointer (might need special const handling in inner type)
    ( (partialarg)
        $def_packed:tt
        $args_packed:tt
        [ $($part_arg:tt)* ]
        [ *const $($arg_rem:tt)* ]
        $ret_packed:tt
    ) => {
        const_ptr_api!( (partialarg) $def_packed $args_packed [ $($part_arg)* *const ] [ $($arg_rem)* ] $ret_packed );
    };
    // finish partial argument with trailing comma
    ( (partialarg)
        $def_packed:tt
        { $($args_tt:tt)* }
        [ $($part_arg:tt)* ]
        [ $arg_ty:ty, $($arg_rem:tt)* ]
        $ret_packed:tt
    ) => {
        const_ptr_api!( (parseargs) $def_packed { $($args_tt)* { $($part_arg)* $arg_ty } } [ $($arg_rem)* ] $ret_packed );
    };
    // finish final partial argument (no trailing comma)
    ( (partialarg)
        $def_packed:tt
        { $($args_tt:tt)* }
        [ $($part_arg:tt)* ]
        [ $arg_ty:ty ]
        $ret_packed:tt
    ) => {
        const_ptr_api!( (parseargs) $def_packed { $($args_tt)* { $($part_arg)* $arg_ty } } [ ] $ret_packed );
    };

    // ----------------------------------------------------------------
    // (parseargs): parsing arguments
    // start next argument
    ( (parseargs)
        $def_packed:tt
        $args_packed:tt
        [ $arg_name:ident : $($arg_rem:tt)* ]
        $ret_packed:tt
    ) => {
        const_ptr_api!( (partialarg) $def_packed $args_packed [ $arg_name: ] [ $($arg_rem)* ] $ret_packed );
    };
    // end of arguments, there is a return type; start parsing it
    ( (parseargs)
        $def_packed:tt
        $args_packed:tt
        [ ]
        [ -> $($rem:tt)* ]
    ) => {
        const_ptr_api!( (partialret) $def_packed $args_packed [] [ $($rem)* ] );
    };
    // end of arguments, no return type
    ( (parseargs)
        $def_packed:tt
        $args_packed:tt
        [ ]
        [ ]
    ) => {
        const_ptr_api!( (generate) $def_packed $args_packed { () } );
    };

    // ----------------------------------------------------------------
    // (partialret): have partial return type, waiting for final return type
    // MAGIC PART 2: hande conditional const ptr in return type
    ( (partialret)
        { $(#[$fn_attr:meta])* pub fn $fn_name:ident }
        $args_packed:tt
        [ $($part_ret:tt)* ]
        [ #[const_ptr_if( $($cfg:tt)* )] $($rem:tt)* ]
    ) => {
        const_ptr_api!( (partialret) { #[cfg($($cfg)*)]      $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_ret)* *const ] [ $($rem)* ] );
        const_ptr_api!( (partialret) { #[cfg(not($($cfg)*))] $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_ret)* *mut   ] [ $($rem)* ] );
    };
    // `* mut` part in return type; continue parsing to find inner conditional const ptr
    ( (partialret)
        $def_packed:tt
        $args_packed:tt
        [ $($part_ret:tt)* ]
        [ *mut $($rem:tt)* ]
    ) => {
        const_ptr_api!( (partialret) $def_packed $args_packed [ $($part_ret)* *mut ] [ $($rem)* ] );
    };
    // `* const` part in return type; continue parsing to find inner conditional const ptr
    ( (partialret)
        $def_packed:tt
        $args_packed:tt
        [ $($part_ret:tt)* ]
        [ *const $($rem:tt)* ]
    ) => {
        const_ptr_api!( (partialret) $def_packed $args_packed [ $($part_ret)* *const ] [ $($rem)* ] );
    };
    // final part of return type
    ( (partialret)
        $def_packed:tt
        $args_packed:tt
        [ $($part_ret:tt)* ]
        [ $ret_ty:ty ]
    ) => {
        const_ptr_api!( (generate) $def_packed $args_packed { $($part_ret)* $ret_ty } );
    };

    // ----------------------------------------------------------------
    // generate
    ( (generate)
        { $(#[$fn_attr:meta])* pub fn $fn_name:ident }
        { $({ $arg_name:ident: $($arg_ty:tt)* })* }
        { $ret_ty:ty }
    ) => {
        extern "C" {
            $(#[$fn_attr])*
            pub fn $fn_name( $(
                $arg_name: $($arg_ty)*
            ),* ) -> $ret_ty;
        }
    };

    // ----------------------------------------------------------------
    // (fn): gather tokens for return type until ";"
    // found end; start parsing current function, and parse remaining functions
    ( (fn)
        $def_packed:tt
        $arg_tts_packed:tt
        $ret_packed:tt
        [ ; $($rem:tt)* ]
    ) => {
        const_ptr_api!( (parseargs) $def_packed {} $arg_tts_packed $ret_packed );
        const_ptr_api!( (extern) [ $($rem)* ] );
    };
    // not ";" - all other tokens are part of the return type.
    // don't expand return type yet; otherwise we'd have to remember in which branch `rem` needs
    // to be used to parse further functions.
    ( (fn)
        $def_packed:tt
        $arg_tts_packed:tt
        [ $($ret_tt:tt)* ]
        [ $tt:tt $($rem:tt)* ]
    ) => {
        const_ptr_api!( (fn) $def_packed $arg_tts_packed [ $($ret_tt)* $tt ] [ $($rem)* ] );
    };

    // ----------------------------------------------------------------
    // (extern): in extern block, find next function
    // try to split into functions as fast as possible to reduce recursion depth
    ( (extern) [
        $(#[$fn_attr:meta])*
        pub fn $fn_name:ident( $($arg_rem:tt)* ) $($rem:tt)*
    ] ) => {
        const_ptr_api!( (fn)
            { $(#[$fn_attr])* pub fn $fn_name } [ $($arg_rem)* ] [] [ $($rem)* ]
        );
    };
    // end of extern block
    ( (extern) [] ) => {};

    // ----------------------------------------------------------------
    // macro start; find extern block
    ( extern "C" { $($rem:tt)* } ) => {
        const_ptr_api!( (extern) [ $($rem)* ] );
    };
}
Loading