/src/open5gs/lib/asn1c/common/asn_internal.c
Line | Count | Source |
1 | | #include <asn_internal.h> |
2 | | |
3 | | #if ASN_EMIT_DEBUG == 1 && __STDC_VERSION__ >= 199901L && !defined(ASN_THREAD_SAFE) |
4 | | int asn_debug_indent = 0; |
5 | | #endif |
6 | | |
7 | | /* |
8 | | * Thread-local encoding recursion depth counters for preventing stack overflow. |
9 | | * Separate counters per format allow independent depth tracking. |
10 | | */ |
11 | | #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) |
12 | | /* C11 thread support */ |
13 | | thread_local int asn1_encoding_depth = 0; /* BER/DER */ |
14 | | thread_local int uper_encoding_depth = 0; /* UPER */ |
15 | | thread_local int aper_encoding_depth = 0; /* APER */ |
16 | | thread_local int oer_encoding_depth = 0; /* OER */ |
17 | | thread_local int xer_encoding_depth = 0; /* XER */ |
18 | | thread_local int jer_encoding_depth = 0; /* JER */ |
19 | | #elif defined(__GNUC__) || defined(__clang__) |
20 | | /* GCC/Clang thread-local extension */ |
21 | | __thread int asn1_encoding_depth = 0; /* BER/DER */ |
22 | | __thread int uper_encoding_depth = 0; /* UPER */ |
23 | | __thread int aper_encoding_depth = 0; /* APER */ |
24 | | __thread int oer_encoding_depth = 0; /* OER */ |
25 | | __thread int xer_encoding_depth = 0; /* XER */ |
26 | | __thread int jer_encoding_depth = 0; /* JER */ |
27 | | #elif defined(_MSC_VER) |
28 | | /* MSVC thread-local */ |
29 | | __declspec(thread) int asn1_encoding_depth = 0; /* BER/DER */ |
30 | | __declspec(thread) int uper_encoding_depth = 0; /* UPER */ |
31 | | __declspec(thread) int aper_encoding_depth = 0; /* APER */ |
32 | | __declspec(thread) int oer_encoding_depth = 0; /* OER */ |
33 | | __declspec(thread) int xer_encoding_depth = 0; /* XER */ |
34 | | __declspec(thread) int jer_encoding_depth = 0; /* JER */ |
35 | | #else |
36 | | /* No thread-local support, use regular variable (not thread-safe) */ |
37 | | int asn1_encoding_depth = 0; /* BER/DER */ |
38 | | int uper_encoding_depth = 0; /* UPER */ |
39 | | int aper_encoding_depth = 0; /* APER */ |
40 | | int oer_encoding_depth = 0; /* OER */ |
41 | | int xer_encoding_depth = 0; /* XER */ |
42 | | int jer_encoding_depth = 0; /* JER */ |
43 | | #endif |
44 | | |
45 | | ssize_t |
46 | | asn__format_to_callback(int (*cb)(const void *, size_t, void *key), void *key, |
47 | 0 | const char *fmt, ...) { |
48 | 0 | char scratch[64]; |
49 | 0 | char *buf = scratch; |
50 | 0 | size_t buf_size = sizeof(scratch); |
51 | 0 | int wrote; |
52 | 0 | int cb_ret; |
53 | |
|
54 | 0 | do { |
55 | 0 | va_list args; |
56 | 0 | va_start(args, fmt); |
57 | |
|
58 | 0 | wrote = vsnprintf(buf, buf_size, fmt, args); |
59 | 0 | va_end(args); |
60 | 0 | if(wrote < (ssize_t)buf_size) { |
61 | 0 | if(wrote < 0) { |
62 | 0 | if(buf != scratch) FREEMEM(buf); |
63 | 0 | return -1; |
64 | 0 | } |
65 | 0 | break; |
66 | 0 | } |
67 | | |
68 | 0 | buf_size <<= 1; |
69 | 0 | if(buf == scratch) { |
70 | 0 | buf = MALLOC(buf_size); |
71 | 0 | if(!buf) { |
72 | 0 | return -1; |
73 | 0 | } |
74 | 0 | } else { |
75 | 0 | void *p = REALLOC(buf, buf_size); |
76 | 0 | if(!p) { |
77 | 0 | FREEMEM(buf); |
78 | 0 | return -1; |
79 | 0 | } |
80 | 0 | buf = p; |
81 | 0 | } |
82 | 0 | } while(1); |
83 | | |
84 | 0 | cb_ret = cb(buf, wrote, key); |
85 | 0 | if(buf != scratch) FREEMEM(buf); |
86 | 0 | if(cb_ret < 0) { |
87 | 0 | return -1; |
88 | 0 | } |
89 | | |
90 | 0 | return wrote; |
91 | 0 | } |
92 | | |