diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c index c81afcbb79..4f4f1dfc23 100644 --- a/crypto/stack/stack.c +++ b/crypto/stack/stack.c @@ -65,16 +65,30 @@ #include "../internal.h" +struct stack_st { + // num contains the number of valid pointers in |data|. + size_t num; + void **data; + // sorted is non-zero if the values pointed to by |data| are in ascending + // order, based on |comp|. + int sorted; + // num_alloc contains the number of pointers allocated in the buffer pointed + // to by |data|, which may be larger than |num|. + size_t num_alloc; + // comp is an optional comparison function. + OPENSSL_sk_cmp_func comp; +}; + // kMinSize is the number of pointers that will be initially allocated in a new // stack. static const size_t kMinSize = 4; -_STACK *sk_new(OPENSSL_sk_cmp_func comp) { - _STACK *ret = OPENSSL_malloc(sizeof(_STACK)); +OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp) { + OPENSSL_STACK *ret = OPENSSL_malloc(sizeof(OPENSSL_STACK)); if (ret == NULL) { return NULL; } - OPENSSL_memset(ret, 0, sizeof(_STACK)); + OPENSSL_memset(ret, 0, sizeof(OPENSSL_STACK)); ret->data = OPENSSL_malloc(sizeof(void *) * kMinSize); if (ret->data == NULL) { @@ -93,16 +107,16 @@ _STACK *sk_new(OPENSSL_sk_cmp_func comp) { return NULL; } -_STACK *sk_new_null(void) { return sk_new(NULL); } +OPENSSL_STACK *OPENSSL_sk_new_null(void) { return OPENSSL_sk_new(NULL); } -size_t sk_num(const _STACK *sk) { +size_t OPENSSL_sk_num(const OPENSSL_STACK *sk) { if (sk == NULL) { return 0; } return sk->num; } -void sk_zero(_STACK *sk) { +void OPENSSL_sk_zero(OPENSSL_STACK *sk) { if (sk == NULL || sk->num == 0) { return; } @@ -111,21 +125,21 @@ void sk_zero(_STACK *sk) { sk->sorted = 0; } -void *sk_value(const _STACK *sk, size_t i) { +void *OPENSSL_sk_value(const OPENSSL_STACK *sk, size_t i) { if (!sk || i >= sk->num) { return NULL; } return sk->data[i]; } -void *sk_set(_STACK *sk, size_t i, void *value) { +void *OPENSSL_sk_set(OPENSSL_STACK *sk, size_t i, void *value) { if (!sk || i >= sk->num) { return NULL; } return sk->data[i] = value; } -void sk_free(_STACK *sk) { +void OPENSSL_sk_free(OPENSSL_STACK *sk) { if (sk == NULL) { return; } @@ -133,8 +147,9 @@ void sk_free(_STACK *sk) { OPENSSL_free(sk); } -void sk_pop_free_ex(_STACK *sk, OPENSSL_sk_call_free_func call_free_func, - OPENSSL_sk_free_func free_func) { +void OPENSSL_sk_pop_free_ex(OPENSSL_STACK *sk, + OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func) { if (sk == NULL) { return; } @@ -144,7 +159,7 @@ void sk_pop_free_ex(_STACK *sk, OPENSSL_sk_call_free_func call_free_func, call_free_func(free_func, sk->data[i]); } } - sk_free(sk); + OPENSSL_sk_free(sk); } // Historically, |sk_pop_free| called the function as |OPENSSL_sk_free_func| @@ -154,11 +169,11 @@ static void call_free_func_legacy(OPENSSL_sk_free_func func, void *ptr) { func(ptr); } -void sk_pop_free(_STACK *sk, OPENSSL_sk_free_func free_func) { - sk_pop_free_ex(sk, call_free_func_legacy, free_func); +void sk_pop_free(OPENSSL_STACK *sk, OPENSSL_sk_free_func free_func) { + OPENSSL_sk_pop_free_ex(sk, call_free_func_legacy, free_func); } -size_t sk_insert(_STACK *sk, void *p, size_t where) { +size_t OPENSSL_sk_insert(OPENSSL_STACK *sk, void *p, size_t where) { if (sk == NULL) { return 0; } @@ -208,7 +223,7 @@ size_t sk_insert(_STACK *sk, void *p, size_t where) { return sk->num; } -void *sk_delete(_STACK *sk, size_t where) { +void *OPENSSL_sk_delete(OPENSSL_STACK *sk, size_t where) { void *ret; if (!sk || where >= sk->num) { @@ -226,22 +241,23 @@ void *sk_delete(_STACK *sk, size_t where) { return ret; } -void *sk_delete_ptr(_STACK *sk, const void *p) { +void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *sk, const void *p) { if (sk == NULL) { return NULL; } for (size_t i = 0; i < sk->num; i++) { if (sk->data[i] == p) { - return sk_delete(sk, i); + return OPENSSL_sk_delete(sk, i); } } return NULL; } -void sk_delete_if(_STACK *sk, OPENSSL_sk_call_delete_if_func call_func, - OPENSSL_sk_delete_if_func func, void *data) { +void OPENSSL_sk_delete_if(OPENSSL_STACK *sk, + OPENSSL_sk_call_delete_if_func call_func, + OPENSSL_sk_delete_if_func func, void *data) { if (sk == NULL) { return; } @@ -256,8 +272,8 @@ void sk_delete_if(_STACK *sk, OPENSSL_sk_call_delete_if_func call_func, sk->num = new_num; } -int sk_find(const _STACK *sk, size_t *out_index, const void *p, - OPENSSL_sk_call_cmp_func call_cmp_func) { +int OPENSSL_sk_find(const OPENSSL_STACK *sk, size_t *out_index, const void *p, + OPENSSL_sk_call_cmp_func call_cmp_func) { if (sk == NULL) { return 0; } @@ -279,7 +295,7 @@ int sk_find(const _STACK *sk, size_t *out_index, const void *p, return 0; } - if (!sk_is_sorted(sk)) { + if (!OPENSSL_sk_is_sorted(sk)) { for (size_t i = 0; i < sk->num; i++) { const void *elem = sk->data[i]; if (call_cmp_func(sk->comp, &p, &elem) == 0) { @@ -327,38 +343,40 @@ int sk_find(const _STACK *sk, size_t *out_index, const void *p, return 0; // Not found. } -void *sk_shift(_STACK *sk) { +void *OPENSSL_sk_shift(OPENSSL_STACK *sk) { if (sk == NULL) { return NULL; } if (sk->num == 0) { return NULL; } - return sk_delete(sk, 0); + return OPENSSL_sk_delete(sk, 0); } -size_t sk_push(_STACK *sk, void *p) { return (sk_insert(sk, p, sk->num)); } +size_t OPENSSL_sk_push(OPENSSL_STACK *sk, void *p) { + return OPENSSL_sk_insert(sk, p, sk->num); +} -void *sk_pop(_STACK *sk) { +void *OPENSSL_sk_pop(OPENSSL_STACK *sk) { if (sk == NULL) { return NULL; } if (sk->num == 0) { return NULL; } - return sk_delete(sk, sk->num - 1); + return OPENSSL_sk_delete(sk, sk->num - 1); } -_STACK *sk_dup(const _STACK *sk) { +OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk) { if (sk == NULL) { return NULL; } - _STACK *ret = OPENSSL_malloc(sizeof(_STACK)); + OPENSSL_STACK *ret = OPENSSL_malloc(sizeof(OPENSSL_STACK)); if (ret == NULL) { return NULL; } - OPENSSL_memset(ret, 0, sizeof(_STACK)); + OPENSSL_memset(ret, 0, sizeof(OPENSSL_STACK)); ret->data = OPENSSL_malloc(sizeof(void *) * sk->num_alloc); if (ret->data == NULL) { @@ -373,7 +391,7 @@ _STACK *sk_dup(const _STACK *sk) { return ret; err: - sk_free(ret); + OPENSSL_sk_free(ret); return NULL; } @@ -389,7 +407,8 @@ static int sort_compare(void *ctx_v, const void *a, const void *b) { } #endif -void sk_sort(_STACK *sk, OPENSSL_sk_call_cmp_func call_cmp_func) { +void OPENSSL_sk_sort(OPENSSL_STACK *sk, + OPENSSL_sk_call_cmp_func call_cmp_func) { if (sk == NULL || sk->comp == NULL || sk->sorted) { return; } @@ -418,7 +437,7 @@ void sk_sort(_STACK *sk, OPENSSL_sk_call_cmp_func call_cmp_func) { sk->sorted = 1; } -int sk_is_sorted(const _STACK *sk) { +int OPENSSL_sk_is_sorted(const OPENSSL_STACK *sk) { if (!sk) { return 1; } @@ -426,7 +445,8 @@ int sk_is_sorted(const _STACK *sk) { return sk->sorted || (sk->comp != NULL && sk->num < 2); } -OPENSSL_sk_cmp_func sk_set_cmp_func(_STACK *sk, OPENSSL_sk_cmp_func comp) { +OPENSSL_sk_cmp_func OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, + OPENSSL_sk_cmp_func comp) { OPENSSL_sk_cmp_func old = sk->comp; if (sk->comp != comp) { @@ -437,11 +457,12 @@ OPENSSL_sk_cmp_func sk_set_cmp_func(_STACK *sk, OPENSSL_sk_cmp_func comp) { return old; } -_STACK *sk_deep_copy(const _STACK *sk, OPENSSL_sk_call_copy_func call_copy_func, - OPENSSL_sk_copy_func copy_func, - OPENSSL_sk_call_free_func call_free_func, - OPENSSL_sk_free_func free_func) { - _STACK *ret = sk_dup(sk); +OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, + OPENSSL_sk_call_copy_func call_copy_func, + OPENSSL_sk_copy_func copy_func, + OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func) { + OPENSSL_STACK *ret = OPENSSL_sk_dup(sk); if (ret == NULL) { return NULL; } @@ -457,7 +478,7 @@ _STACK *sk_deep_copy(const _STACK *sk, OPENSSL_sk_call_copy_func call_copy_func, call_free_func(free_func, ret->data[j]); } } - sk_free(ret); + OPENSSL_sk_free(ret); return NULL; } } diff --git a/include/openssl/stack.h b/include/openssl/stack.h index e2b9d3187d..239b4306bf 100644 --- a/include/openssl/stack.h +++ b/include/openssl/stack.h @@ -247,8 +247,11 @@ STACK_OF(SAMPLE) *sk_SAMPLE_deep_copy(const STACK_OF(SAMPLE) *sk, // Private functions. // -// TODO(https://crbug.com/boringssl/499): Rename to |OPENSSL_sk_foo|, after -// external code that calls them is fixed. +// The |sk_*| functions generated above are implemented internally using the +// type-erased functions below. Callers should use the typed wrappers instead. +// When using the type-erased functions, callers are responsible for ensuring +// the underlying types are correct. Casting pointers to the wrong types will +// result in memory errors. // OPENSSL_sk_free_func is a function that frees an element in a stack. Note its // actual type is void (*)(T *) for some T. Low-level |sk_*| functions will be @@ -284,63 +287,83 @@ typedef int (*OPENSSL_sk_call_cmp_func)(OPENSSL_sk_cmp_func, typedef int (*OPENSSL_sk_call_delete_if_func)(OPENSSL_sk_delete_if_func, void *, void *); -// stack_st contains an array of pointers. It is not designed to be used +// An OPENSSL_STACK contains an array of pointers. It is not designed to be used // directly, rather the wrapper macros should be used. -typedef struct stack_st { - // num contains the number of valid pointers in |data|. - size_t num; - void **data; - // sorted is non-zero if the values pointed to by |data| are in ascending - // order, based on |comp|. - int sorted; - // num_alloc contains the number of pointers allocated in the buffer pointed - // to by |data|, which may be larger than |num|. - size_t num_alloc; - // comp is an optional comparison function. - OPENSSL_sk_cmp_func comp; -} _STACK; +typedef struct stack_st OPENSSL_STACK; // The following are raw stack functions. They implement the corresponding typed // |sk_SAMPLE_*| functions generated by |DEFINE_STACK_OF|. Callers shouldn't be // using them. Rather, callers should use the typed functions. -OPENSSL_EXPORT _STACK *sk_new(OPENSSL_sk_cmp_func comp); -OPENSSL_EXPORT _STACK *sk_new_null(void); -OPENSSL_EXPORT size_t sk_num(const _STACK *sk); -OPENSSL_EXPORT void sk_zero(_STACK *sk); -OPENSSL_EXPORT void *sk_value(const _STACK *sk, size_t i); -OPENSSL_EXPORT void *sk_set(_STACK *sk, size_t i, void *p); -OPENSSL_EXPORT void sk_free(_STACK *sk); -OPENSSL_EXPORT void sk_pop_free_ex(_STACK *sk, - OPENSSL_sk_call_free_func call_free_func, - OPENSSL_sk_free_func free_func); -OPENSSL_EXPORT size_t sk_insert(_STACK *sk, void *p, size_t where); -OPENSSL_EXPORT void *sk_delete(_STACK *sk, size_t where); -OPENSSL_EXPORT void *sk_delete_ptr(_STACK *sk, const void *p); -OPENSSL_EXPORT void sk_delete_if(_STACK *sk, - OPENSSL_sk_call_delete_if_func call_func, - OPENSSL_sk_delete_if_func func, void *data); -OPENSSL_EXPORT int sk_find(const _STACK *sk, size_t *out_index, const void *p, - OPENSSL_sk_call_cmp_func call_cmp_func); -OPENSSL_EXPORT void *sk_shift(_STACK *sk); -OPENSSL_EXPORT size_t sk_push(_STACK *sk, void *p); -OPENSSL_EXPORT void *sk_pop(_STACK *sk); -OPENSSL_EXPORT _STACK *sk_dup(const _STACK *sk); -OPENSSL_EXPORT void sk_sort(_STACK *sk, OPENSSL_sk_call_cmp_func call_cmp_func); -OPENSSL_EXPORT int sk_is_sorted(const _STACK *sk); -OPENSSL_EXPORT OPENSSL_sk_cmp_func sk_set_cmp_func(_STACK *sk, - OPENSSL_sk_cmp_func comp); -OPENSSL_EXPORT _STACK *sk_deep_copy(const _STACK *sk, - OPENSSL_sk_call_copy_func call_copy_func, - OPENSSL_sk_copy_func copy_func, - OPENSSL_sk_call_free_func call_free_func, - OPENSSL_sk_free_func free_func); +OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp); +OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new_null(void); +OPENSSL_EXPORT size_t OPENSSL_sk_num(const OPENSSL_STACK *sk); +OPENSSL_EXPORT void OPENSSL_sk_zero(OPENSSL_STACK *sk); +OPENSSL_EXPORT void *OPENSSL_sk_value(const OPENSSL_STACK *sk, size_t i); +OPENSSL_EXPORT void *OPENSSL_sk_set(OPENSSL_STACK *sk, size_t i, void *p); +OPENSSL_EXPORT void OPENSSL_sk_free(OPENSSL_STACK *sk); +OPENSSL_EXPORT void OPENSSL_sk_pop_free_ex( + OPENSSL_STACK *sk, OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func); +OPENSSL_EXPORT size_t OPENSSL_sk_insert(OPENSSL_STACK *sk, void *p, + size_t where); +OPENSSL_EXPORT void *OPENSSL_sk_delete(OPENSSL_STACK *sk, size_t where); +OPENSSL_EXPORT void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *sk, const void *p); +OPENSSL_EXPORT void OPENSSL_sk_delete_if( + OPENSSL_STACK *sk, OPENSSL_sk_call_delete_if_func call_func, + OPENSSL_sk_delete_if_func func, void *data); +OPENSSL_EXPORT int OPENSSL_sk_find(const OPENSSL_STACK *sk, size_t *out_index, + const void *p, + OPENSSL_sk_call_cmp_func call_cmp_func); +OPENSSL_EXPORT void *OPENSSL_sk_shift(OPENSSL_STACK *sk); +OPENSSL_EXPORT size_t OPENSSL_sk_push(OPENSSL_STACK *sk, void *p); +OPENSSL_EXPORT void *OPENSSL_sk_pop(OPENSSL_STACK *sk); +OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk); +OPENSSL_EXPORT void OPENSSL_sk_sort(OPENSSL_STACK *sk, + OPENSSL_sk_call_cmp_func call_cmp_func); +OPENSSL_EXPORT int OPENSSL_sk_is_sorted(const OPENSSL_STACK *sk); +OPENSSL_EXPORT OPENSSL_sk_cmp_func +OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_cmp_func comp); +OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_deep_copy( + const OPENSSL_STACK *sk, OPENSSL_sk_call_copy_func call_copy_func, + OPENSSL_sk_copy_func copy_func, OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func); + + +// Deprecated private functions (hidden). +// +// TODO(crbug.com/boringssl/499): Migrate callers to the typed wrappers, or at +// least the new names and remove the old ones. + +typedef OPENSSL_STACK _STACK; + +OPENSSL_INLINE OPENSSL_STACK *sk_new_null(void) { + return OPENSSL_sk_new_null(); +} + +OPENSSL_INLINE size_t sk_num(const OPENSSL_STACK *sk) { + return OPENSSL_sk_num(sk); +} + +OPENSSL_INLINE void *sk_value(const OPENSSL_STACK *sk, size_t i) { + return OPENSSL_sk_value(sk, i); +} + +OPENSSL_INLINE void sk_free(OPENSSL_STACK *sk) { OPENSSL_sk_free(sk); } + +OPENSSL_INLINE size_t sk_push(OPENSSL_STACK *sk, void *p) { + return OPENSSL_sk_push(sk, p); +} + +OPENSSL_INLINE void *sk_pop(OPENSSL_STACK *sk) { return OPENSSL_sk_pop(sk); } // sk_pop_free behaves like |sk_pop_free_ex| but performs an invalid function // pointer cast. It exists because some existing callers called |sk_pop_free| // directly. // // TODO(davidben): Migrate callers to bssl::UniquePtr and remove this. -OPENSSL_EXPORT void sk_pop_free(_STACK *sk, OPENSSL_sk_free_func free_func); +OPENSSL_EXPORT void sk_pop_free(OPENSSL_STACK *sk, + OPENSSL_sk_free_func free_func); + #if !defined(BORINGSSL_NO_CXX) extern "C++" { @@ -370,153 +393,154 @@ BSSL_NAMESPACE_END #define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) #endif -#define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \ - /* We disable MSVC C4191 in this macro, which warns when pointers are cast \ - * to the wrong type. While the cast itself is valid, it is often a bug \ - * because calling it through the cast is UB. However, we never actually \ - * call functions as |OPENSSL_sk_cmp_func|. The type is just a type-erased \ - * function pointer. (C does not guarantee function pointers fit in \ - * |void*|, and GCC will warn on this.) Thus we just disable the false \ - * positive warning. */ \ - OPENSSL_MSVC_PRAGMA(warning(push)) \ - OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) \ - \ - DECLARE_STACK_OF(name) \ - \ - typedef void (*sk_##name##_free_func)(ptrtype); \ - typedef ptrtype (*sk_##name##_copy_func)(constptrtype); \ - typedef int (*sk_##name##_cmp_func)(constptrtype const *, \ - constptrtype const *); \ - typedef int (*sk_##name##_delete_if_func)(ptrtype, void *); \ - \ - OPENSSL_INLINE void sk_##name##_call_free_func( \ - OPENSSL_sk_free_func free_func, void *ptr) { \ - ((sk_##name##_free_func)free_func)((ptrtype)ptr); \ - } \ - \ - OPENSSL_INLINE void *sk_##name##_call_copy_func( \ - OPENSSL_sk_copy_func copy_func, const void *ptr) { \ - return (void *)((sk_##name##_copy_func)copy_func)((constptrtype)ptr); \ - } \ - \ - OPENSSL_INLINE int sk_##name##_call_cmp_func(OPENSSL_sk_cmp_func cmp_func, \ - const void *const *a, \ - const void *const *b) { \ - /* The data is actually stored as |void*| pointers, so read the pointer \ - * as |void*| and then pass the corrected type into the caller-supplied \ - * function, which expects |constptrtype*|. */ \ - constptrtype a_ptr = (constptrtype)*a; \ - constptrtype b_ptr = (constptrtype)*b; \ - return ((sk_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ - } \ - \ - OPENSSL_INLINE int sk_##name##_call_delete_if_func( \ - OPENSSL_sk_delete_if_func func, void *obj, void *data) { \ - return ((sk_##name##_delete_if_func)func)((ptrtype)obj, data); \ - } \ - \ - OPENSSL_INLINE STACK_OF(name) *sk_##name##_new(sk_##name##_cmp_func comp) { \ - return (STACK_OF(name) *)sk_new((OPENSSL_sk_cmp_func)comp); \ - } \ - \ - OPENSSL_INLINE STACK_OF(name) *sk_##name##_new_null(void) { \ - return (STACK_OF(name) *)sk_new_null(); \ - } \ - \ - OPENSSL_INLINE size_t sk_##name##_num(const STACK_OF(name) *sk) { \ - return sk_num((const _STACK *)sk); \ - } \ - \ - OPENSSL_INLINE void sk_##name##_zero(STACK_OF(name) *sk) { \ - sk_zero((_STACK *)sk); \ - } \ - \ - OPENSSL_INLINE ptrtype sk_##name##_value(const STACK_OF(name) *sk, \ - size_t i) { \ - return (ptrtype)sk_value((const _STACK *)sk, i); \ - } \ - \ - OPENSSL_INLINE ptrtype sk_##name##_set(STACK_OF(name) *sk, size_t i, \ - ptrtype p) { \ - return (ptrtype)sk_set((_STACK *)sk, i, (void *)p); \ - } \ - \ - OPENSSL_INLINE void sk_##name##_free(STACK_OF(name) *sk) { \ - sk_free((_STACK *)sk); \ - } \ - \ - OPENSSL_INLINE void sk_##name##_pop_free(STACK_OF(name) *sk, \ - sk_##name##_free_func free_func) { \ - sk_pop_free_ex((_STACK *)sk, sk_##name##_call_free_func, \ - (OPENSSL_sk_free_func)free_func); \ - } \ - \ - OPENSSL_INLINE size_t sk_##name##_insert(STACK_OF(name) *sk, ptrtype p, \ - size_t where) { \ - return sk_insert((_STACK *)sk, (void *)p, where); \ - } \ - \ - OPENSSL_INLINE ptrtype sk_##name##_delete(STACK_OF(name) *sk, \ - size_t where) { \ - return (ptrtype)sk_delete((_STACK *)sk, where); \ - } \ - \ - OPENSSL_INLINE ptrtype sk_##name##_delete_ptr(STACK_OF(name) *sk, \ - constptrtype p) { \ - return (ptrtype)sk_delete_ptr((_STACK *)sk, (const void *)p); \ - } \ - \ - OPENSSL_INLINE void sk_##name##_delete_if( \ - STACK_OF(name) *sk, sk_##name##_delete_if_func func, void *data) { \ - sk_delete_if((_STACK *)sk, sk_##name##_call_delete_if_func, \ - (OPENSSL_sk_delete_if_func)func, data); \ - } \ - \ - OPENSSL_INLINE int sk_##name##_find(const STACK_OF(name) *sk, \ - size_t *out_index, constptrtype p) { \ - return sk_find((const _STACK *)sk, out_index, (const void *)p, \ - sk_##name##_call_cmp_func); \ - } \ - \ - OPENSSL_INLINE ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \ - return (ptrtype)sk_shift((_STACK *)sk); \ - } \ - \ - OPENSSL_INLINE size_t sk_##name##_push(STACK_OF(name) *sk, ptrtype p) { \ - return sk_push((_STACK *)sk, (void *)p); \ - } \ - \ - OPENSSL_INLINE ptrtype sk_##name##_pop(STACK_OF(name) *sk) { \ - return (ptrtype)sk_pop((_STACK *)sk); \ - } \ - \ - OPENSSL_INLINE STACK_OF(name) *sk_##name##_dup(const STACK_OF(name) *sk) { \ - return (STACK_OF(name) *)sk_dup((const _STACK *)sk); \ - } \ - \ - OPENSSL_INLINE void sk_##name##_sort(STACK_OF(name) *sk) { \ - sk_sort((_STACK *)sk, sk_##name##_call_cmp_func); \ - } \ - \ - OPENSSL_INLINE int sk_##name##_is_sorted(const STACK_OF(name) *sk) { \ - return sk_is_sorted((const _STACK *)sk); \ - } \ - \ - OPENSSL_INLINE sk_##name##_cmp_func sk_##name##_set_cmp_func( \ - STACK_OF(name) *sk, sk_##name##_cmp_func comp) { \ - return (sk_##name##_cmp_func)sk_set_cmp_func((_STACK *)sk, \ - (OPENSSL_sk_cmp_func)comp); \ - } \ - \ - OPENSSL_INLINE STACK_OF(name) *sk_##name##_deep_copy( \ - const STACK_OF(name) *sk, sk_##name##_copy_func copy_func, \ - sk_##name##_free_func free_func) { \ - return (STACK_OF(name) *)sk_deep_copy( \ - (const _STACK *)sk, sk_##name##_call_copy_func, \ - (OPENSSL_sk_copy_func)copy_func, sk_##name##_call_free_func, \ - (OPENSSL_sk_free_func)free_func); \ - } \ - \ +#define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \ + /* We disable MSVC C4191 in this macro, which warns when pointers are cast \ + * to the wrong type. While the cast itself is valid, it is often a bug \ + * because calling it through the cast is UB. However, we never actually \ + * call functions as |OPENSSL_sk_cmp_func|. The type is just a type-erased \ + * function pointer. (C does not guarantee function pointers fit in \ + * |void*|, and GCC will warn on this.) Thus we just disable the false \ + * positive warning. */ \ + OPENSSL_MSVC_PRAGMA(warning(push)) \ + OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) \ + \ + DECLARE_STACK_OF(name) \ + \ + typedef void (*sk_##name##_free_func)(ptrtype); \ + typedef ptrtype (*sk_##name##_copy_func)(constptrtype); \ + typedef int (*sk_##name##_cmp_func)(constptrtype const *, \ + constptrtype const *); \ + typedef int (*sk_##name##_delete_if_func)(ptrtype, void *); \ + \ + OPENSSL_INLINE void sk_##name##_call_free_func( \ + OPENSSL_sk_free_func free_func, void *ptr) { \ + ((sk_##name##_free_func)free_func)((ptrtype)ptr); \ + } \ + \ + OPENSSL_INLINE void *sk_##name##_call_copy_func( \ + OPENSSL_sk_copy_func copy_func, const void *ptr) { \ + return (void *)((sk_##name##_copy_func)copy_func)((constptrtype)ptr); \ + } \ + \ + OPENSSL_INLINE int sk_##name##_call_cmp_func(OPENSSL_sk_cmp_func cmp_func, \ + const void *const *a, \ + const void *const *b) { \ + /* The data is actually stored as |void*| pointers, so read the pointer \ + * as |void*| and then pass the corrected type into the caller-supplied \ + * function, which expects |constptrtype*|. */ \ + constptrtype a_ptr = (constptrtype)*a; \ + constptrtype b_ptr = (constptrtype)*b; \ + return ((sk_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ + } \ + \ + OPENSSL_INLINE int sk_##name##_call_delete_if_func( \ + OPENSSL_sk_delete_if_func func, void *obj, void *data) { \ + return ((sk_##name##_delete_if_func)func)((ptrtype)obj, data); \ + } \ + \ + OPENSSL_INLINE STACK_OF(name) *sk_##name##_new(sk_##name##_cmp_func comp) { \ + return (STACK_OF(name) *)OPENSSL_sk_new((OPENSSL_sk_cmp_func)comp); \ + } \ + \ + OPENSSL_INLINE STACK_OF(name) *sk_##name##_new_null(void) { \ + return (STACK_OF(name) *)OPENSSL_sk_new_null(); \ + } \ + \ + OPENSSL_INLINE size_t sk_##name##_num(const STACK_OF(name) *sk) { \ + return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_zero(STACK_OF(name) *sk) { \ + OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_value(const STACK_OF(name) *sk, \ + size_t i) { \ + return (ptrtype)OPENSSL_sk_value((const OPENSSL_STACK *)sk, i); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_set(STACK_OF(name) *sk, size_t i, \ + ptrtype p) { \ + return (ptrtype)OPENSSL_sk_set((OPENSSL_STACK *)sk, i, (void *)p); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_free(STACK_OF(name) *sk) { \ + OPENSSL_sk_free((OPENSSL_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_pop_free(STACK_OF(name) *sk, \ + sk_##name##_free_func free_func) { \ + OPENSSL_sk_pop_free_ex((OPENSSL_STACK *)sk, sk_##name##_call_free_func, \ + (OPENSSL_sk_free_func)free_func); \ + } \ + \ + OPENSSL_INLINE size_t sk_##name##_insert(STACK_OF(name) *sk, ptrtype p, \ + size_t where) { \ + return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (void *)p, where); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_delete(STACK_OF(name) *sk, \ + size_t where) { \ + return (ptrtype)OPENSSL_sk_delete((OPENSSL_STACK *)sk, where); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_delete_ptr(STACK_OF(name) *sk, \ + constptrtype p) { \ + return (ptrtype)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ + (const void *)p); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_delete_if( \ + STACK_OF(name) *sk, sk_##name##_delete_if_func func, void *data) { \ + OPENSSL_sk_delete_if((OPENSSL_STACK *)sk, sk_##name##_call_delete_if_func, \ + (OPENSSL_sk_delete_if_func)func, data); \ + } \ + \ + OPENSSL_INLINE int sk_##name##_find(const STACK_OF(name) *sk, \ + size_t *out_index, constptrtype p) { \ + return OPENSSL_sk_find((const OPENSSL_STACK *)sk, out_index, \ + (const void *)p, sk_##name##_call_cmp_func); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \ + return (ptrtype)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE size_t sk_##name##_push(STACK_OF(name) *sk, ptrtype p) { \ + return OPENSSL_sk_push((OPENSSL_STACK *)sk, (void *)p); \ + } \ + \ + OPENSSL_INLINE ptrtype sk_##name##_pop(STACK_OF(name) *sk) { \ + return (ptrtype)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE STACK_OF(name) *sk_##name##_dup(const STACK_OF(name) *sk) { \ + return (STACK_OF(name) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_sort(STACK_OF(name) *sk) { \ + OPENSSL_sk_sort((OPENSSL_STACK *)sk, sk_##name##_call_cmp_func); \ + } \ + \ + OPENSSL_INLINE int sk_##name##_is_sorted(const STACK_OF(name) *sk) { \ + return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ + } \ + \ + OPENSSL_INLINE sk_##name##_cmp_func sk_##name##_set_cmp_func( \ + STACK_OF(name) *sk, sk_##name##_cmp_func comp) { \ + return (sk_##name##_cmp_func)OPENSSL_sk_set_cmp_func( \ + (OPENSSL_STACK *)sk, (OPENSSL_sk_cmp_func)comp); \ + } \ + \ + OPENSSL_INLINE STACK_OF(name) *sk_##name##_deep_copy( \ + const STACK_OF(name) *sk, sk_##name##_copy_func copy_func, \ + sk_##name##_free_func free_func) { \ + return (STACK_OF(name) *)OPENSSL_sk_deep_copy( \ + (const OPENSSL_STACK *)sk, sk_##name##_call_copy_func, \ + (OPENSSL_sk_copy_func)copy_func, sk_##name##_call_free_func, \ + (OPENSSL_sk_free_func)free_func); \ + } \ + \ OPENSSL_MSVC_PRAGMA(warning(pop)) @@ -545,7 +569,7 @@ namespace internal { template struct DeleterImpl< Stack, typename std::enable_if::kIsConst>::type> { - static void Free(Stack *sk) { sk_free(reinterpret_cast<_STACK *>(sk)); } + static void Free(Stack *sk) { OPENSSL_sk_free(reinterpret_cast(sk)); } }; // Stacks defined with |DEFINE_STACK_OF| are freed with |sk_pop_free| and the @@ -557,11 +581,12 @@ struct DeleterImpl< // sk_FOO_pop_free is defined by macros and bound by name, so we cannot // access it from C++ here. using Type = typename StackTraits::Type; - sk_pop_free_ex(reinterpret_cast<_STACK *>(sk), - [](OPENSSL_sk_free_func /* unused */, void *ptr) { - DeleterImpl::Free(reinterpret_cast(ptr)); - }, - nullptr); + OPENSSL_sk_pop_free_ex( + reinterpret_cast(sk), + [](OPENSSL_sk_free_func /* unused */, void *ptr) { + DeleterImpl::Free(reinterpret_cast(ptr)); + }, + nullptr); } }; @@ -582,7 +607,7 @@ class StackIteratorImpl { Type *operator*() const { return reinterpret_cast( - sk_value(reinterpret_cast(sk_), idx_)); + OPENSSL_sk_value(reinterpret_cast(sk_), idx_)); } StackIteratorImpl &operator++(/* prefix */) { @@ -614,10 +639,10 @@ inline typename std::enable_if::kIsConst, bool>::type PushToStack(Stack *sk, UniquePtr::Type> elem) { - if (!sk_push(reinterpret_cast<_STACK *>(sk), elem.get())) { + if (!OPENSSL_sk_push(reinterpret_cast(sk), elem.get())) { return false; } - // sk_push takes ownership on success. + // OPENSSL_sk_push takes ownership on success. elem.release(); return true; } @@ -633,7 +658,7 @@ inline bssl::internal::StackIterator begin(const Stack *sk) { template inline bssl::internal::StackIterator end(const Stack *sk) { return bssl::internal::StackIterator( - sk, sk_num(reinterpret_cast(sk))); + sk, OPENSSL_sk_num(reinterpret_cast(sk))); } } // extern C++