File: | build-scan/../src/resolve/resolved-dns-question.c |
Warning: | line 313, column 33 Potential leak of memory pointed to by 'q' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include "alloc-util.h" | |||
4 | #include "dns-domain.h" | |||
5 | #include "dns-type.h" | |||
6 | #include "resolved-dns-question.h" | |||
7 | ||||
8 | DnsQuestion *dns_question_new(size_t n) { | |||
9 | DnsQuestion *q; | |||
10 | ||||
11 | assert(n > 0)do { if ((__builtin_expect(!!(!(n > 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("n > 0"), "../src/resolve/resolved-dns-question.c" , 11, __PRETTY_FUNCTION__); } while (0); | |||
12 | ||||
13 | q = malloc0(offsetof(DnsQuestion, keys) + sizeof(DnsResourceKey*) * n)(calloc(1, (__builtin_offsetof(DnsQuestion, keys) + sizeof(DnsResourceKey *) * n))); | |||
14 | if (!q) | |||
15 | return NULL((void*)0); | |||
16 | ||||
17 | q->n_ref = 1; | |||
18 | q->n_allocated = n; | |||
19 | ||||
20 | return q; | |||
21 | } | |||
22 | ||||
23 | DnsQuestion *dns_question_ref(DnsQuestion *q) { | |||
24 | if (!q) | |||
25 | return NULL((void*)0); | |||
26 | ||||
27 | assert(q->n_ref > 0)do { if ((__builtin_expect(!!(!(q->n_ref > 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("q->n_ref > 0"), "../src/resolve/resolved-dns-question.c" , 27, __PRETTY_FUNCTION__); } while (0); | |||
28 | q->n_ref++; | |||
29 | return q; | |||
30 | } | |||
31 | ||||
32 | DnsQuestion *dns_question_unref(DnsQuestion *q) { | |||
33 | if (!q) | |||
34 | return NULL((void*)0); | |||
35 | ||||
36 | assert(q->n_ref > 0)do { if ((__builtin_expect(!!(!(q->n_ref > 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("q->n_ref > 0"), "../src/resolve/resolved-dns-question.c" , 36, __PRETTY_FUNCTION__); } while (0); | |||
37 | ||||
38 | if (q->n_ref == 1) { | |||
39 | size_t i; | |||
40 | ||||
41 | for (i = 0; i < q->n_keys; i++) | |||
42 | dns_resource_key_unref(q->keys[i]); | |||
43 | free(q); | |||
44 | } else | |||
45 | q->n_ref--; | |||
46 | ||||
47 | return NULL((void*)0); | |||
48 | } | |||
49 | ||||
50 | int dns_question_add(DnsQuestion *q, DnsResourceKey *key) { | |||
51 | size_t i; | |||
52 | int r; | |||
53 | ||||
54 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/resolve/resolved-dns-question.c" , 54, __PRETTY_FUNCTION__); } while (0); | |||
55 | ||||
56 | if (!q) | |||
57 | return -ENOSPC28; | |||
58 | ||||
59 | for (i = 0; i < q->n_keys; i++) { | |||
60 | r = dns_resource_key_equal(q->keys[i], key); | |||
61 | if (r < 0) | |||
62 | return r; | |||
63 | if (r > 0) | |||
64 | return 0; | |||
65 | } | |||
66 | ||||
67 | if (q->n_keys >= q->n_allocated) | |||
68 | return -ENOSPC28; | |||
69 | ||||
70 | q->keys[q->n_keys++] = dns_resource_key_ref(key); | |||
71 | return 0; | |||
72 | } | |||
73 | ||||
74 | int dns_question_matches_rr(DnsQuestion *q, DnsResourceRecord *rr, const char *search_domain) { | |||
75 | size_t i; | |||
76 | int r; | |||
77 | ||||
78 | assert(rr)do { if ((__builtin_expect(!!(!(rr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rr"), "../src/resolve/resolved-dns-question.c" , 78, __PRETTY_FUNCTION__); } while (0); | |||
79 | ||||
80 | if (!q) | |||
81 | return 0; | |||
82 | ||||
83 | for (i = 0; i < q->n_keys; i++) { | |||
84 | r = dns_resource_key_match_rr(q->keys[i], rr, search_domain); | |||
85 | if (r != 0) | |||
86 | return r; | |||
87 | } | |||
88 | ||||
89 | return 0; | |||
90 | } | |||
91 | ||||
92 | int dns_question_matches_cname_or_dname(DnsQuestion *q, DnsResourceRecord *rr, const char *search_domain) { | |||
93 | size_t i; | |||
94 | int r; | |||
95 | ||||
96 | assert(rr)do { if ((__builtin_expect(!!(!(rr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rr"), "../src/resolve/resolved-dns-question.c" , 96, __PRETTY_FUNCTION__); } while (0); | |||
97 | ||||
98 | if (!q) | |||
99 | return 0; | |||
100 | ||||
101 | if (!IN_SET(rr->key->type, DNS_TYPE_CNAME, DNS_TYPE_DNAME)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){DNS_TYPE_CNAME, DNS_TYPE_DNAME})/sizeof( int)]; switch(rr->key->type) { case DNS_TYPE_CNAME: case DNS_TYPE_DNAME: _found = 1; break; default: break; } _found; })) | |||
102 | return 0; | |||
103 | ||||
104 | for (i = 0; i < q->n_keys; i++) { | |||
105 | /* For a {C,D}NAME record we can never find a matching {C,D}NAME record */ | |||
106 | if (!dns_type_may_redirect(q->keys[i]->type)) | |||
107 | return 0; | |||
108 | ||||
109 | r = dns_resource_key_match_cname_or_dname(q->keys[i], rr->key, search_domain); | |||
110 | if (r != 0) | |||
111 | return r; | |||
112 | } | |||
113 | ||||
114 | return 0; | |||
115 | } | |||
116 | ||||
117 | int dns_question_is_valid_for_query(DnsQuestion *q) { | |||
118 | const char *name; | |||
119 | size_t i; | |||
120 | int r; | |||
121 | ||||
122 | if (!q) | |||
123 | return 0; | |||
124 | ||||
125 | if (q->n_keys <= 0) | |||
126 | return 0; | |||
127 | ||||
128 | if (q->n_keys > 65535) | |||
129 | return 0; | |||
130 | ||||
131 | name = dns_resource_key_name(q->keys[0]); | |||
132 | if (!name) | |||
133 | return 0; | |||
134 | ||||
135 | /* Check that all keys in this question bear the same name */ | |||
136 | for (i = 0; i < q->n_keys; i++) { | |||
137 | assert(q->keys[i])do { if ((__builtin_expect(!!(!(q->keys[i])),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("q->keys[i]"), "../src/resolve/resolved-dns-question.c" , 137, __PRETTY_FUNCTION__); } while (0); | |||
138 | ||||
139 | if (i > 0) { | |||
140 | r = dns_name_equal(dns_resource_key_name(q->keys[i]), name); | |||
141 | if (r <= 0) | |||
142 | return r; | |||
143 | } | |||
144 | ||||
145 | if (!dns_type_is_valid_query(q->keys[i]->type)) | |||
146 | return 0; | |||
147 | } | |||
148 | ||||
149 | return 1; | |||
150 | } | |||
151 | ||||
152 | int dns_question_contains(DnsQuestion *a, const DnsResourceKey *k) { | |||
153 | size_t j; | |||
154 | int r; | |||
155 | ||||
156 | assert(k)do { if ((__builtin_expect(!!(!(k)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("k"), "../src/resolve/resolved-dns-question.c" , 156, __PRETTY_FUNCTION__); } while (0); | |||
157 | ||||
158 | if (!a) | |||
159 | return 0; | |||
160 | ||||
161 | for (j = 0; j < a->n_keys; j++) { | |||
162 | r = dns_resource_key_equal(a->keys[j], k); | |||
163 | if (r != 0) | |||
164 | return r; | |||
165 | } | |||
166 | ||||
167 | return 0; | |||
168 | } | |||
169 | ||||
170 | int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b) { | |||
171 | size_t j; | |||
172 | int r; | |||
173 | ||||
174 | if (a == b) | |||
175 | return 1; | |||
176 | ||||
177 | if (!a) | |||
178 | return !b || b->n_keys == 0; | |||
179 | if (!b) | |||
180 | return a->n_keys == 0; | |||
181 | ||||
182 | /* Checks if all keys in a are also contained b, and vice versa */ | |||
183 | ||||
184 | for (j = 0; j < a->n_keys; j++) { | |||
185 | r = dns_question_contains(b, a->keys[j]); | |||
186 | if (r <= 0) | |||
187 | return r; | |||
188 | } | |||
189 | ||||
190 | for (j = 0; j < b->n_keys; j++) { | |||
191 | r = dns_question_contains(a, b->keys[j]); | |||
192 | if (r <= 0) | |||
193 | return r; | |||
194 | } | |||
195 | ||||
196 | return 1; | |||
197 | } | |||
198 | ||||
199 | int dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname, DnsQuestion **ret) { | |||
200 | _cleanup_(dns_question_unrefp)__attribute__((cleanup(dns_question_unrefp))) DnsQuestion *n = NULL((void*)0); | |||
201 | DnsResourceKey *key; | |||
202 | bool_Bool same = true1; | |||
203 | int r; | |||
204 | ||||
205 | assert(cname)do { if ((__builtin_expect(!!(!(cname)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("cname"), "../src/resolve/resolved-dns-question.c" , 205, __PRETTY_FUNCTION__); } while (0); | |||
206 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/resolve/resolved-dns-question.c" , 206, __PRETTY_FUNCTION__); } while (0); | |||
207 | assert(IN_SET(cname->key->type, DNS_TYPE_CNAME, DNS_TYPE_DNAME))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){DNS_TYPE_CNAME, DNS_TYPE_DNAME})/sizeof(int )]; switch(cname->key->type) { case DNS_TYPE_CNAME: case DNS_TYPE_DNAME: _found = 1; break; default: break; } _found; }))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("IN_SET(cname->key->type, DNS_TYPE_CNAME, DNS_TYPE_DNAME)" ), "../src/resolve/resolved-dns-question.c", 207, __PRETTY_FUNCTION__ ); } while (0); | |||
208 | ||||
209 | if (dns_question_size(q) <= 0) { | |||
210 | *ret = NULL((void*)0); | |||
211 | return 0; | |||
212 | } | |||
213 | ||||
214 | DNS_QUESTION_FOREACH(key, q)for (size_t __unique_prefix_i7 = ({ (key) = ((q) && ( q)->n_keys > 0) ? (q)->keys[0] : ((void*)0); 0; }); ( q) && (__unique_prefix_i7 < (q)->n_keys); __unique_prefix_i7 ++, (key) = (__unique_prefix_i7 < (q)->n_keys ? (q)-> keys[__unique_prefix_i7] : ((void*)0))) { | |||
215 | _cleanup_free___attribute__((cleanup(freep))) char *destination = NULL((void*)0); | |||
216 | const char *d; | |||
217 | ||||
218 | if (cname->key->type == DNS_TYPE_CNAME) | |||
219 | d = cname->cname.name; | |||
220 | else { | |||
221 | r = dns_name_change_suffix(dns_resource_key_name(key), dns_resource_key_name(cname->key), cname->dname.name, &destination); | |||
222 | if (r < 0) | |||
223 | return r; | |||
224 | if (r == 0) | |||
225 | continue; | |||
226 | ||||
227 | d = destination; | |||
228 | } | |||
229 | ||||
230 | r = dns_name_equal(dns_resource_key_name(key), d); | |||
231 | if (r < 0) | |||
232 | return r; | |||
233 | ||||
234 | if (r == 0) { | |||
235 | same = false0; | |||
236 | break; | |||
237 | } | |||
238 | } | |||
239 | ||||
240 | /* Fully the same, indicate we didn't do a thing */ | |||
241 | if (same) { | |||
242 | *ret = NULL((void*)0); | |||
243 | return 0; | |||
244 | } | |||
245 | ||||
246 | n = dns_question_new(q->n_keys); | |||
247 | if (!n) | |||
248 | return -ENOMEM12; | |||
249 | ||||
250 | /* Create a new question, and patch in the new name */ | |||
251 | DNS_QUESTION_FOREACH(key, q)for (size_t __unique_prefix_i8 = ({ (key) = ((q) && ( q)->n_keys > 0) ? (q)->keys[0] : ((void*)0); 0; }); ( q) && (__unique_prefix_i8 < (q)->n_keys); __unique_prefix_i8 ++, (key) = (__unique_prefix_i8 < (q)->n_keys ? (q)-> keys[__unique_prefix_i8] : ((void*)0))) { | |||
252 | _cleanup_(dns_resource_key_unrefp)__attribute__((cleanup(dns_resource_key_unrefp))) DnsResourceKey *k = NULL((void*)0); | |||
253 | ||||
254 | k = dns_resource_key_new_redirect(key, cname); | |||
255 | if (!k) | |||
256 | return -ENOMEM12; | |||
257 | ||||
258 | r = dns_question_add(n, k); | |||
259 | if (r < 0) | |||
260 | return r; | |||
261 | } | |||
262 | ||||
263 | *ret = TAKE_PTR(n)({ typeof(n) _ptr_ = (n); (n) = ((void*)0); _ptr_; }); | |||
264 | ||||
265 | return 1; | |||
266 | } | |||
267 | ||||
268 | const char *dns_question_first_name(DnsQuestion *q) { | |||
269 | ||||
270 | if (!q) | |||
271 | return NULL((void*)0); | |||
272 | ||||
273 | if (q->n_keys < 1) | |||
274 | return NULL((void*)0); | |||
275 | ||||
276 | return dns_resource_key_name(q->keys[0]); | |||
277 | } | |||
278 | ||||
279 | int dns_question_new_address(DnsQuestion **ret, int family, const char *name, bool_Bool convert_idna) { | |||
280 | _cleanup_(dns_question_unrefp)__attribute__((cleanup(dns_question_unrefp))) DnsQuestion *q = NULL((void*)0); | |||
281 | _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0); | |||
282 | int r; | |||
283 | ||||
284 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/resolve/resolved-dns-question.c" , 284, __PRETTY_FUNCTION__); } while (0); | |||
| ||||
285 | assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("name"), "../src/resolve/resolved-dns-question.c" , 285, __PRETTY_FUNCTION__); } while (0); | |||
286 | ||||
287 | if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){2, 10, 0})/sizeof(int)]; switch(family) { case 2: case 10: case 0: _found = 1; break; default: break; } _found; })) | |||
288 | return -EAFNOSUPPORT97; | |||
289 | ||||
290 | if (convert_idna) { | |||
291 | r = dns_name_apply_idna(name, &buf); | |||
292 | if (r < 0) | |||
293 | return r; | |||
294 | if (r > 0 && !streq(name, buf)(strcmp((name),(buf)) == 0)) | |||
295 | name = buf; | |||
296 | else | |||
297 | /* We did not manage to create convert the idna name, or it's | |||
298 | * the same as the original name. We assume the caller already | |||
299 | * created an uncoverted question, so let's not repeat work | |||
300 | * unnecessarily. */ | |||
301 | return -EALREADY114; | |||
302 | } | |||
303 | ||||
304 | q = dns_question_new(family
| |||
305 | if (!q
| |||
306 | return -ENOMEM12; | |||
307 | ||||
308 | if (family
| |||
309 | _cleanup_(dns_resource_key_unrefp)__attribute__((cleanup(dns_resource_key_unrefp))) DnsResourceKey *key = NULL((void*)0); | |||
310 | ||||
311 | key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, name); | |||
312 | if (!key) | |||
313 | return -ENOMEM12; | |||
| ||||
314 | ||||
315 | r = dns_question_add(q, key); | |||
316 | if (r < 0) | |||
317 | return r; | |||
318 | } | |||
319 | ||||
320 | if (family != AF_INET2) { | |||
321 | _cleanup_(dns_resource_key_unrefp)__attribute__((cleanup(dns_resource_key_unrefp))) DnsResourceKey *key = NULL((void*)0); | |||
322 | ||||
323 | key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, name); | |||
324 | if (!key) | |||
325 | return -ENOMEM12; | |||
326 | ||||
327 | r = dns_question_add(q, key); | |||
328 | if (r < 0) | |||
329 | return r; | |||
330 | } | |||
331 | ||||
332 | *ret = TAKE_PTR(q)({ typeof(q) _ptr_ = (q); (q) = ((void*)0); _ptr_; }); | |||
333 | ||||
334 | return 0; | |||
335 | } | |||
336 | ||||
337 | int dns_question_new_reverse(DnsQuestion **ret, int family, const union in_addr_union *a) { | |||
338 | _cleanup_(dns_resource_key_unrefp)__attribute__((cleanup(dns_resource_key_unrefp))) DnsResourceKey *key = NULL((void*)0); | |||
339 | _cleanup_(dns_question_unrefp)__attribute__((cleanup(dns_question_unrefp))) DnsQuestion *q = NULL((void*)0); | |||
340 | _cleanup_free___attribute__((cleanup(freep))) char *reverse = NULL((void*)0); | |||
341 | int r; | |||
342 | ||||
343 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/resolve/resolved-dns-question.c" , 343, __PRETTY_FUNCTION__); } while (0); | |||
344 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/resolve/resolved-dns-question.c" , 344, __PRETTY_FUNCTION__); } while (0); | |||
345 | ||||
346 | if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){2, 10, 0})/sizeof(int)]; switch(family) { case 2: case 10: case 0: _found = 1; break; default: break; } _found; })) | |||
347 | return -EAFNOSUPPORT97; | |||
348 | ||||
349 | r = dns_name_reverse(family, a, &reverse); | |||
350 | if (r < 0) | |||
351 | return r; | |||
352 | ||||
353 | q = dns_question_new(1); | |||
354 | if (!q) | |||
355 | return -ENOMEM12; | |||
356 | ||||
357 | key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, reverse); | |||
358 | if (!key) | |||
359 | return -ENOMEM12; | |||
360 | ||||
361 | reverse = NULL((void*)0); | |||
362 | ||||
363 | r = dns_question_add(q, key); | |||
364 | if (r < 0) | |||
365 | return r; | |||
366 | ||||
367 | *ret = TAKE_PTR(q)({ typeof(q) _ptr_ = (q); (q) = ((void*)0); _ptr_; }); | |||
368 | ||||
369 | return 0; | |||
370 | } | |||
371 | ||||
372 | int dns_question_new_service( | |||
373 | DnsQuestion **ret, | |||
374 | const char *service, | |||
375 | const char *type, | |||
376 | const char *domain, | |||
377 | bool_Bool with_txt, | |||
378 | bool_Bool convert_idna) { | |||
379 | ||||
380 | _cleanup_(dns_resource_key_unrefp)__attribute__((cleanup(dns_resource_key_unrefp))) DnsResourceKey *key = NULL((void*)0); | |||
381 | _cleanup_(dns_question_unrefp)__attribute__((cleanup(dns_question_unrefp))) DnsQuestion *q = NULL((void*)0); | |||
382 | _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0), *joined = NULL((void*)0); | |||
383 | const char *name; | |||
384 | int r; | |||
385 | ||||
386 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/resolve/resolved-dns-question.c" , 386, __PRETTY_FUNCTION__); } while (0); | |||
387 | ||||
388 | /* We support three modes of invocation: | |||
389 | * | |||
390 | * 1. Only a domain is specified, in which case we assume a properly encoded SRV RR name, including service | |||
391 | * type and possibly a service name. If specified in this way we assume it's already IDNA converted if | |||
392 | * that's necessary. | |||
393 | * | |||
394 | * 2. Both service type and a domain specified, in which case a normal SRV RR is assumed, without a DNS-SD | |||
395 | * style prefix. In this case we'll IDNA convert the domain, if that's requested. | |||
396 | * | |||
397 | * 3. All three of service name, type and domain are specified, in which case a DNS-SD service is put | |||
398 | * together. The service name is never IDNA converted, and the domain is if requested. | |||
399 | * | |||
400 | * It's not supported to specify a service name without a type, or no domain name. | |||
401 | */ | |||
402 | ||||
403 | if (!domain) | |||
404 | return -EINVAL22; | |||
405 | ||||
406 | if (type) { | |||
407 | if (convert_idna) { | |||
408 | r = dns_name_apply_idna(domain, &buf); | |||
409 | if (r < 0) | |||
410 | return r; | |||
411 | if (r > 0) | |||
412 | domain = buf; | |||
413 | } | |||
414 | ||||
415 | r = dns_service_join(service, type, domain, &joined); | |||
416 | if (r < 0) | |||
417 | return r; | |||
418 | ||||
419 | name = joined; | |||
420 | } else { | |||
421 | if (service) | |||
422 | return -EINVAL22; | |||
423 | ||||
424 | name = domain; | |||
425 | } | |||
426 | ||||
427 | q = dns_question_new(1 + with_txt); | |||
428 | if (!q) | |||
429 | return -ENOMEM12; | |||
430 | ||||
431 | key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SRV, name); | |||
432 | if (!key) | |||
433 | return -ENOMEM12; | |||
434 | ||||
435 | r = dns_question_add(q, key); | |||
436 | if (r < 0) | |||
437 | return r; | |||
438 | ||||
439 | if (with_txt) { | |||
440 | dns_resource_key_unref(key); | |||
441 | key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_TXT, name); | |||
442 | if (!key) | |||
443 | return -ENOMEM12; | |||
444 | ||||
445 | r = dns_question_add(q, key); | |||
446 | if (r < 0) | |||
447 | return r; | |||
448 | } | |||
449 | ||||
450 | *ret = TAKE_PTR(q)({ typeof(q) _ptr_ = (q); (q) = ((void*)0); _ptr_; }); | |||
451 | ||||
452 | return 0; | |||
453 | } |