Trả lời ngắn: OPENSSL_free
phải được sử dụng miễn phí buf
.
Câu trả lời dài: IMPLEMENT_ASN1_FUNCTIONS
macro được mở rộng thành định nghĩa của hàm i2d_X509
. Ví dụ dưới đây cho thấy rằng, đặt mã nguồn sau vào một source.c
:
#include <openssl/asn1t.h>
IMPLEMENT_ASN1_FUNCTIONS(X509)
Sau khi thực hiện các gcc -E source.c
vĩ mô được mở rộng để:
X509 *d2i_X509(X509 **a, const unsigned char **in, long len) { return (X509 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (&(X509_it))); }
int i2d_X509(X509 *a, unsigned char **out) { return ASN1_item_i2d((ASN1_VALUE *)a, out, (&(X509_it))); }
X509 *X509_new(void) { return (X509 *)ASN1_item_new((&(X509_it))); }
void X509_free(X509 *a) { ASN1_item_free((ASN1_VALUE *)a, (&(X509_it))); }
các địa điểm ưa thích là định nghĩa của i2d_X509
, lần lượt mà gọi hàm ASN1_item_i2d
. Theo mã nguồn của openssl, ASN1_item_i2d
là một chức năng được xác định trong tasn_enc.c
file:
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
const ASN1_ITEM *it, int flags)
{
if (out && !*out) {
unsigned char *p, *buf;
int len;
len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
if (len <= 0)
return len;
buf = OPENSSL_malloc(len);
if (buf == NULL)
return -1;
p = buf;
ASN1_item_ex_i2d(&val, &p, it, -1, flags);
*out = buf;
return len;
}
return ASN1_item_ex_i2d(&val, out, it, -1, flags);
}
Nhánh if (out && !*out)
được sử dụng trong một trường hợp được mô tả trong câu hỏi ban đầu (buf
là NULL
). Vì vậy, nội bộ, openssl phân bổ bộ nhớ cho buf
sử dụng OPENSSL_malloc
và kết quả là OPENSSL_free
phải được sử dụng để deallocate bộ nhớ.
Lưu ý: Tôi đã xem mã nguồn của openssl khả dụng trên GH vào thời điểm hiện tại.
Assuption của bạn có vẻ đúng với tôi. –
@MichaelWalz, hy vọng như vậy. Nhưng hành vi không được xác định, ví dụ: nó có thể xảy ra rằng nó sẽ là cần thiết để buf miễn phí ngay cả khi lỗi xảy ra. – tysonite