/src/openssl/crypto/asprintf.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | | * this file except in compliance with the License. You can obtain a copy |
6 | | * in the file LICENSE in the source distribution or at |
7 | | * https://www.openssl.org/source/license.html |
8 | | */ |
9 | | |
10 | | #include <stdarg.h> |
11 | | #include <stdio.h> |
12 | | #include <openssl/crypto.h> |
13 | | #include "internal/cryptlib.h" |
14 | | |
15 | | int ossl_vasprintf(char **str, const char *format, va_list args) |
16 | 16 | { |
17 | 16 | char *candidate = NULL; |
18 | 16 | size_t candidate_len = 64; |
19 | 16 | size_t tmp_len = 0; |
20 | 16 | char *tmp = NULL; |
21 | 16 | int ret; |
22 | | |
23 | 16 | if ((candidate = OPENSSL_malloc(candidate_len)) == NULL) |
24 | 0 | goto err; |
25 | 16 | va_list args_copy; |
26 | 16 | va_copy(args_copy, args); |
27 | 16 | ret = vsnprintf(candidate, candidate_len, format, args_copy); |
28 | 16 | va_end(args_copy); |
29 | 16 | if (ret < 0) |
30 | 0 | goto err; |
31 | 16 | if ((size_t)ret >= candidate_len) { |
32 | | /* Too big to fit in allocation. */ |
33 | |
|
34 | 0 | tmp_len = (size_t)ret + 1; |
35 | 0 | if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) |
36 | 0 | goto err; |
37 | 0 | OPENSSL_clear_free(candidate, candidate_len); |
38 | 0 | candidate = tmp; |
39 | 0 | candidate_len = tmp_len; |
40 | 0 | tmp = NULL; |
41 | 0 | ret = vsnprintf(candidate, candidate_len, format, args); |
42 | 0 | } |
43 | | /* At this point this should not happen unless vsnprintf is insane. */ |
44 | 16 | if (ret < 0 || (size_t)ret >= candidate_len) |
45 | 0 | goto err; |
46 | 16 | *str = candidate; |
47 | 16 | return ret; |
48 | | |
49 | 0 | err: |
50 | 0 | OPENSSL_clear_free(candidate, candidate_len); |
51 | 0 | OPENSSL_clear_free(tmp, tmp_len); |
52 | 0 | *str = NULL; |
53 | 0 | return -1; |
54 | 16 | } |
55 | | |
56 | | int ossl_asprintf(char **str, const char *format, ...) |
57 | 16 | { |
58 | 16 | va_list args; |
59 | 16 | int ret; |
60 | | |
61 | 16 | va_start(args, format); |
62 | 16 | ret = ossl_vasprintf(str, format, args); |
63 | | va_end(args); |
64 | 16 | return ret; |
65 | 16 | } |