Bug Summary

File:libs/apr/strings/apr_snprintf.c
Location:line 518, column 1
Description:Address of stack memory associated with local variable 'is_negative' is still referred to by the global variable 'is_negative' upon returning to the caller. This will be a dangling reference

Annotated Source Code

1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "apr.h"
18#include "apr_private.h"
19
20#include "apr_lib.h"
21#include "apr_strings.h"
22#include "apr_network_io.h"
23#include "apr_portable.h"
24#include <math.h>
25#if APR_HAVE_CTYPE_H1
26#include <ctype.h>
27#endif
28#if APR_HAVE_NETINET_IN_H1
29#include <netinet/in.h>
30#endif
31#if APR_HAVE_SYS_SOCKET_H1
32#include <sys/socket.h>
33#endif
34#if APR_HAVE_ARPA_INET_H1
35#include <arpa/inet.h>
36#endif
37#if APR_HAVE_LIMITS_H1
38#include <limits.h>
39#endif
40#if APR_HAVE_STRING_H1
41#include <string.h>
42#endif
43
44typedef enum {
45 NO = 0, YES = 1
46} boolean_e;
47
48#ifndef FALSE0
49#define FALSE0 0
50#endif
51#ifndef TRUE(!0)
52#define TRUE(!0) 1
53#endif
54#define NUL'\0' '\0'
55#define WIDE_INTlong long
56
57typedef WIDE_INTlong wide_int;
58typedef unsigned WIDE_INTlong u_wide_int;
59typedef apr_int64_t widest_int;
60#ifdef __TANDEM
61/* Although Tandem supports "long long" there is no unsigned variant. */
62typedef unsigned long u_widest_int;
63#else
64typedef apr_uint64_t u_widest_int;
65#endif
66typedef int bool_int;
67
68#define S_NULL"(null)" "(null)"
69#define S_NULL_LEN6 6
70
71#define FLOAT_DIGITS6 6
72#define EXPONENT_LENGTH10 10
73
74/*
75 * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
76 *
77 * NOTICE: this is a magic number; do not decrease it
78 */
79#define NUM_BUF_SIZE512 512
80
81/*
82 * cvt.c - IEEE floating point formatting routines for FreeBSD
83 * from GNU libc-4.6.27. Modified to be thread safe.
84 */
85
86/*
87 * apr_ecvt converts to decimal
88 * the number of digits is specified by ndigit
89 * decpt is set to the position of the decimal point
90 * sign is set to 0 for positive, 1 for negative
91 */
92
93#define NDIG80 80
94
95/* buf must have at least NDIG bytes */
96static char *apr_cvt(double arg, int ndigits, int *decpt, int *sign,
97 int eflag, char *buf)
98{
99 register int r2;
100 double fi, fj;
101 register char *p, *p1;
102
103 if (ndigits >= NDIG80 - 1)
104 ndigits = NDIG80 - 2;
105 r2 = 0;
106 *sign = 0;
107 p = &buf[0];
108 if (arg < 0) {
109 *sign = 1;
110 arg = -arg;
111 }
112 arg = modf(arg, &fi);
113 p1 = &buf[NDIG80];
114 /*
115 * Do integer part
116 */
117 if (fi != 0) {
118 p1 = &buf[NDIG80];
119 while (p1 > &buf[0] && fi != 0) {
120 fj = modf(fi / 10, &fi);
121 *--p1 = (int) ((fj + .03) * 10) + '0';
122 r2++;
123 }
124 while (p1 < &buf[NDIG80])
125 *p++ = *p1++;
126 }
127 else if (arg > 0) {
128 while ((fj = arg * 10) < 1) {
129 arg = fj;
130 r2--;
131 }
132 }
133 p1 = &buf[ndigits];
134 if (eflag == 0)
135 p1 += r2;
136 if (p1 < &buf[0]) {
137 *decpt = -ndigits;
138 buf[0] = '\0';
139 return (buf);
140 }
141 *decpt = r2;
142 while (p <= p1 && p < &buf[NDIG80]) {
143 arg *= 10;
144 arg = modf(arg, &fj);
145 *p++ = (int) fj + '0';
146 }
147 if (p1 >= &buf[NDIG80]) {
148 buf[NDIG80 - 1] = '\0';
149 return (buf);
150 }
151 p = p1;
152 *p1 += 5;
153 while (*p1 > '9') {
154 *p1 = '0';
155 if (p1 > buf)
156 ++ * --p1;
157 else {
158 *p1 = '1';
159 (*decpt)++;
160 if (eflag == 0) {
161 if (p > buf)
162 *p = '0';
163 p++;
164 }
165 }
166 }
167 *p = '\0';
168 return (buf);
169}
170
171static char *apr_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
172{
173 return (apr_cvt(arg, ndigits, decpt, sign, 1, buf));
174}
175
176static char *apr_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
177{
178 return (apr_cvt(arg, ndigits, decpt, sign, 0, buf));
179}
180
181/*
182 * apr_gcvt - Floating output conversion to
183 * minimal length string
184 */
185
186static char *apr_gcvt(double number, int ndigit, char *buf, boolean_e altform)
187{
188 int sign, decpt;
189 register char *p1, *p2;
190 register int i;
191 char buf1[NDIG80];
192
193 p1 = apr_ecvt(number, ndigit, &decpt, &sign, buf1);
194 p2 = buf;
195 if (sign)
196 *p2++ = '-';
197 for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--)
198 ndigit--;
199 if ((decpt >= 0 && decpt - ndigit > 4)
200 || (decpt < 0 && decpt < -3)) { /* use E-style */
201 decpt--;
202 *p2++ = *p1++;
203 *p2++ = '.';
204 for (i = 1; i < ndigit; i++)
205 *p2++ = *p1++;
206 *p2++ = 'e';
207 if (decpt < 0) {
208 decpt = -decpt;
209 *p2++ = '-';
210 }
211 else
212 *p2++ = '+';
213 if (decpt / 100 > 0)
214 *p2++ = decpt / 100 + '0';
215 if (decpt / 10 > 0)
216 *p2++ = (decpt % 100) / 10 + '0';
217 *p2++ = decpt % 10 + '0';
218 }
219 else {
220 if (decpt <= 0) {
221 if (*p1 != '0')
222 *p2++ = '.';
223 while (decpt < 0) {
224 decpt++;
225 *p2++ = '0';
226 }
227 }
228 for (i = 1; i <= ndigit; i++) {
229 *p2++ = *p1++;
230 if (i == decpt)
231 *p2++ = '.';
232 }
233 if (ndigit < decpt) {
234 while (ndigit++ < decpt)
235 *p2++ = '0';
236 *p2++ = '.';
237 }
238 }
239 if (p2[-1] == '.' && !altform)
240 p2--;
241 *p2 = '\0';
242 return (buf);
243}
244
245/*
246 * The INS_CHAR macro inserts a character in the buffer and writes
247 * the buffer back to disk if necessary
248 * It uses the char pointers sp and bep:
249 * sp points to the next available character in the buffer
250 * bep points to the end-of-buffer+1
251 * While using this macro, note that the nextb pointer is NOT updated.
252 *
253 * NOTE: Evaluation of the c argument should not have any side-effects
254 */
255#define INS_CHAR(c, sp, bep, cc){ if (sp) { if (sp >= bep) { vbuff->curpos = sp; if (flush_func
(vbuff)) return -1; sp = vbuff->curpos; bep = vbuff->endpos
; } *sp++ = (c); } cc++; }
\
256{ \
257 if (sp) { \
258 if (sp >= bep) { \
259 vbuff->curpos = sp; \
260 if (flush_func(vbuff)) \
261 return -1; \
262 sp = vbuff->curpos; \
263 bep = vbuff->endpos; \
264 } \
265 *sp++ = (c); \
266 } \
267 cc++; \
268}
269
270#define NUM(c)(c - '0') (c - '0')
271
272#define STR_TO_DEC(str, num)num = (*str++ - '0'); while ((((*__ctype_b_loc ())[(int) ((((
unsigned char)(*str))))] & (unsigned short int) _ISdigit)
)) { num *= 10 ; num += (*str++ - '0'); }
\
273 num = NUM(*str++)(*str++ - '0'); \
274 while (apr_isdigit(*str)(((*__ctype_b_loc ())[(int) ((((unsigned char)(*str))))] &
(unsigned short int) _ISdigit))
) \
275 { \
276 num *= 10 ; \
277 num += NUM(*str++)(*str++ - '0'); \
278 }
279
280/*
281 * This macro does zero padding so that the precision
282 * requirement is satisfied. The padding is done by
283 * adding '0's to the left of the string that is going
284 * to be printed. We don't allow precision to be large
285 * enough that we continue past the start of s.
286 *
287 * NOTE: this makes use of the magic info that s is
288 * always based on num_buf with a size of NUM_BUF_SIZE.
289 */
290#define FIX_PRECISION(adjust, precision, s, s_len)if (adjust) { apr_size_t p = (precision + 1 < 512) ? precision
: 512 - 1; while (s_len < p) { *--s = '0'; s_len++; } }
\
291 if (adjust) { \
292 apr_size_t p = (precision + 1 < NUM_BUF_SIZE512) \
293 ? precision : NUM_BUF_SIZE512 - 1; \
294 while (s_len < p) \
295 { \
296 *--s = '0'; \
297 s_len++; \
298 } \
299 }
300
301/*
302 * Macro that does padding. The padding is done by printing
303 * the character ch.
304 */
305#define PAD(width, len, ch)do { { if (sp) { if (sp >= bep) { vbuff->curpos = sp; if
(flush_func(vbuff)) return -1; sp = vbuff->curpos; bep = vbuff
->endpos; } *sp++ = (ch); } cc++; }; width--; } while (width
> len)
\
306do \
307{ \
308 INS_CHAR(ch, sp, bep, cc){ if (sp) { if (sp >= bep) { vbuff->curpos = sp; if (flush_func
(vbuff)) return -1; sp = vbuff->curpos; bep = vbuff->endpos
; } *sp++ = (ch); } cc++; }
; \
309 width--; \
310} \
311while (width > len)
312
313/*
314 * Prefix the character ch to the string str
315 * Increase length
316 * Set the has_prefix flag
317 */
318#define PREFIX(str, length, ch)*--str = ch; length++; has_prefix=YES; \
319 *--str = ch; \
320 length++; \
321 has_prefix=YES;
322
323
324/*
325 * Convert num to its decimal format.
326 * Return value:
327 * - a pointer to a string containing the number (no sign)
328 * - len contains the length of the string
329 * - is_negative is set to TRUE or FALSE depending on the sign
330 * of the number (always set to FALSE if is_unsigned is TRUE)
331 *
332 * The caller provides a buffer for the string: that is the buf_end argument
333 * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
334 * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
335 *
336 * Note: we have 2 versions. One is used when we need to use quads
337 * (conv_10_quad), the other when we don't (conv_10). We're assuming the
338 * latter is faster.
339 */
340static char *conv_10(register wide_int num, register bool_int is_unsigned,
341 register bool_int *is_negative, char *buf_end,
342 register apr_size_t *len)
343{
344 register char *p = buf_end;
345 register u_wide_int magnitude;
346
347 if (is_unsigned) {
348 magnitude = (u_wide_int) num;
349 *is_negative = FALSE0;
350 }
351 else {
352 *is_negative = (num < 0);
353
354 /*
355 * On a 2's complement machine, negating the most negative integer
356 * results in a number that cannot be represented as a signed integer.
357 * Here is what we do to obtain the number's magnitude:
358 * a. add 1 to the number
359 * b. negate it (becomes positive)
360 * c. convert it to unsigned
361 * d. add 1
362 */
363 if (*is_negative) {
364 wide_int t = num + 1;
365
366 magnitude = ((u_wide_int) -t) + 1;
367 }
368 else
369 magnitude = (u_wide_int) num;
370 }
371
372 /*
373 * We use a do-while loop so that we write at least 1 digit
374 */
375 do {
376 register u_wide_int new_magnitude = magnitude / 10;
377
378 *--p = (char) (magnitude - new_magnitude * 10 + '0');
379 magnitude = new_magnitude;
380 }
381 while (magnitude);
382
383 *len = buf_end - p;
384 return (p);
385}
386
387static char *conv_10_quad(widest_int num, register bool_int is_unsigned,
388 register bool_int *is_negative, char *buf_end,
389 register apr_size_t *len)
390{
391 register char *p = buf_end;
392 u_widest_int magnitude;
393
394 /*
395 * We see if we can use the faster non-quad version by checking the
396 * number against the largest long value it can be. If <=, we
397 * punt to the quicker version.
398 */
399 if ((num <= ULONG_MAX(9223372036854775807L *2UL+1UL) && is_unsigned)
400 || (num <= LONG_MAX9223372036854775807L && num >= LONG_MIN(-9223372036854775807L -1L) && !is_unsigned))
401 return(conv_10( (wide_int)num, is_unsigned, is_negative,
402 buf_end, len));
403
404 if (is_unsigned) {
405 magnitude = (u_widest_int) num;
406 *is_negative = FALSE0;
407 }
408 else {
409 *is_negative = (num < 0);
410
411 /*
412 * On a 2's complement machine, negating the most negative integer
413 * results in a number that cannot be represented as a signed integer.
414 * Here is what we do to obtain the number's magnitude:
415 * a. add 1 to the number
416 * b. negate it (becomes positive)
417 * c. convert it to unsigned
418 * d. add 1
419 */
420 if (*is_negative) {
421 widest_int t = num + 1;
422
423 magnitude = ((u_widest_int) -t) + 1;
424 }
425 else
426 magnitude = (u_widest_int) num;
427 }
428
429 /*
430 * We use a do-while loop so that we write at least 1 digit
431 */
432 do {
433 u_widest_int new_magnitude = magnitude / 10;
434
435 *--p = (char) (magnitude - new_magnitude * 10 + '0');
436 magnitude = new_magnitude;
437 }
438 while (magnitude);
439
440 *len = buf_end - p;
441 return (p);
442}
443
444
445
446static char *conv_in_addr(struct in_addr *ia, char *buf_end, apr_size_t *len)
447{
448 unsigned addr = ntohl(ia->s_addr)(__extension__ ({ unsigned int __v, __x = (ia->s_addr); if
(__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
449 char *p = buf_end;
450 bool_int is_negative;
451 apr_size_t sub_len;
452
453 p = conv_10((addr & 0x000000FF) , TRUE(!0), &is_negative, p, &sub_len);
454 *--p = '.';
455 p = conv_10((addr & 0x0000FF00) >> 8, TRUE(!0), &is_negative, p, &sub_len);
456 *--p = '.';
457 p = conv_10((addr & 0x00FF0000) >> 16, TRUE(!0), &is_negative, p, &sub_len);
458 *--p = '.';
459 p = conv_10((addr & 0xFF000000) >> 24, TRUE(!0), &is_negative, p, &sub_len);
460
461 *len = buf_end - p;
462 return (p);
463}
464
465
466
467static char *conv_apr_sockaddr(apr_sockaddr_t *sa, char *buf_end, apr_size_t *len)
468{
469 char *p = buf_end;
470 bool_int is_negative;
471 apr_size_t sub_len;
472 char *ipaddr_str;
473
474 p = conv_10(sa->port, TRUE(!0), &is_negative, p, &sub_len);
475 *--p = ':';
476 apr_sockaddr_ip_get(&ipaddr_str, sa);
477 sub_len = strlen(ipaddr_str);
478#if APR_HAVE_IPV61
479 if (sa->family == APR_INET610 &&
480 !IN6_IS_ADDR_V4MAPPED(&sa->sa.sin6.sin6_addr)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (&sa->sa.sin6.sin6_addr); __a->__in6_u.__u6_addr32
[0] == 0 && __a->__in6_u.__u6_addr32[1] == 0 &&
__a->__in6_u.__u6_addr32[2] == (__extension__ ({ unsigned
int __v, __x = (0xffff); if (__builtin_constant_p (__x)) __v
= ((((__x) & 0xff000000) >> 24) | (((__x) & 0x00ff0000
) >> 8) | (((__x) & 0x0000ff00) << 8) | (((__x
) & 0x000000ff) << 24)); else __asm__ ("bswap %0" :
"=r" (__v) : "0" (__x)); __v; })); }))
) {
481 *(p - 1) = ']';
482 p -= sub_len + 2;
483 *p = '[';
484 memcpy(p + 1, ipaddr_str, sub_len);
485 }
486 else
487#endif
488 {
489 p -= sub_len;
490 memcpy(p, ipaddr_str, sub_len);
491 }
492
493 *len = buf_end - p;
494 return (p);
495}
496
497
498
499#if APR_HAS_THREADS1
500static char *conv_os_thread_t(apr_os_thread_t *tid, char *buf_end, apr_size_t *len)
501{
502 union {
503 apr_os_thread_t tid;
504 apr_uint64_t alignme;
505 } u;
506 int is_negative;
507
508 u.tid = *tid;
509 switch(sizeof(u.tid)) {
39
Control jumps to 'case 8:' at line 512
510 case sizeof(apr_int32_t):
511 return conv_10(*(apr_uint32_t *)&u.tid, TRUE(!0), &is_negative, buf_end, len);
512 case sizeof(apr_int64_t):
513 return conv_10_quad(*(apr_uint64_t *)&u.tid, TRUE(!0), &is_negative, buf_end, len);
514 default:
515 /* not implemented; stick 0 in the buffer */
516 return conv_10(0, TRUE(!0), &is_negative, buf_end, len);
517 }
518}
40
Address of stack memory associated with local variable 'is_negative' is still referred to by the global variable 'is_negative' upon returning to the caller. This will be a dangling reference
519#endif
520
521
522
523/*
524 * Convert a floating point number to a string formats 'f', 'e' or 'E'.
525 * The result is placed in buf, and len denotes the length of the string
526 * The sign is returned in the is_negative argument (and is not placed
527 * in buf).
528 */
529static char *conv_fp(register char format, register double num,
530 boolean_e add_dp, int precision, bool_int *is_negative,
531 char *buf, apr_size_t *len)
532{
533 register char *s = buf;
534 register char *p;
535 int decimal_point;
536 char buf1[NDIG80];
537
538 if (format == 'f')
539 p = apr_fcvt(num, precision, &decimal_point, is_negative, buf1);
540 else /* either e or E format */
541 p = apr_ecvt(num, precision + 1, &decimal_point, is_negative, buf1);
542
543 /*
544 * Check for Infinity and NaN
545 */
546 if (apr_isalpha(*p)(((*__ctype_b_loc ())[(int) ((((unsigned char)(*p))))] & (
unsigned short int) _ISalpha))
) {
547 *len = strlen(p);
548 memcpy(buf, p, *len + 1);
549 *is_negative = FALSE0;
550 return (buf);
551 }
552
553 if (format == 'f') {
554 if (decimal_point <= 0) {
555 *s++ = '0';
556 if (precision > 0) {
557 *s++ = '.';
558 while (decimal_point++ < 0)
559 *s++ = '0';
560 }
561 else if (add_dp)
562 *s++ = '.';
563 }
564 else {
565 while (decimal_point-- > 0)
566 *s++ = *p++;
567 if (precision > 0 || add_dp)
568 *s++ = '.';
569 }
570 }
571 else {
572 *s++ = *p++;
573 if (precision > 0 || add_dp)
574 *s++ = '.';
575 }
576
577 /*
578 * copy the rest of p, the NUL is NOT copied
579 */
580 while (*p)
581 *s++ = *p++;
582
583 if (format != 'f') {
584 char temp[EXPONENT_LENGTH10]; /* for exponent conversion */
585 apr_size_t t_len;
586 bool_int exponent_is_negative;
587
588 *s++ = format; /* either e or E */
589 decimal_point--;
590 if (decimal_point != 0) {
591 p = conv_10((wide_int) decimal_point, FALSE0, &exponent_is_negative,
592 &temp[EXPONENT_LENGTH10], &t_len);
593 *s++ = exponent_is_negative ? '-' : '+';
594
595 /*
596 * Make sure the exponent has at least 2 digits
597 */
598 if (t_len == 1)
599 *s++ = '0';
600 while (t_len--)
601 *s++ = *p++;
602 }
603 else {
604 *s++ = '+';
605 *s++ = '0';
606 *s++ = '0';
607 }
608 }
609
610 *len = s - buf;
611 return (buf);
612}
613
614
615/*
616 * Convert num to a base X number where X is a power of 2. nbits determines X.
617 * For example, if nbits is 3, we do base 8 conversion
618 * Return value:
619 * a pointer to a string containing the number
620 *
621 * The caller provides a buffer for the string: that is the buf_end argument
622 * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
623 * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
624 *
625 * As with conv_10, we have a faster version which is used when
626 * the number isn't quad size.
627 */
628static char *conv_p2(register u_wide_int num, register int nbits,
629 char format, char *buf_end, register apr_size_t *len)
630{
631 register int mask = (1 << nbits) - 1;
632 register char *p = buf_end;
633 static const char low_digits[] = "0123456789abcdef";
634 static const char upper_digits[] = "0123456789ABCDEF";
635 register const char *digits = (format == 'X') ? upper_digits : low_digits;
636
637 do {
638 *--p = digits[num & mask];
639 num >>= nbits;
640 }
641 while (num);
642
643 *len = buf_end - p;
644 return (p);
645}
646
647static char *conv_p2_quad(u_widest_int num, register int nbits,
648 char format, char *buf_end, register apr_size_t *len)
649{
650 register int mask = (1 << nbits) - 1;
651 register char *p = buf_end;
652 static const char low_digits[] = "0123456789abcdef";
653 static const char upper_digits[] = "0123456789ABCDEF";
654 register const char *digits = (format == 'X') ? upper_digits : low_digits;
655
656 if (num <= ULONG_MAX(9223372036854775807L *2UL+1UL))
657 return(conv_p2((u_wide_int)num, nbits, format, buf_end, len));
658
659 do {
660 *--p = digits[num & mask];
661 num >>= nbits;
662 }
663 while (num);
664
665 *len = buf_end - p;
666 return (p);
667}
668
669#if APR_HAS_THREADS1
670static char *conv_os_thread_t_hex(apr_os_thread_t *tid, char *buf_end, apr_size_t *len)
671{
672 union {
673 apr_os_thread_t tid;
674 apr_uint64_t alignme;
675 } u;
676 int is_negative;
677
678 u.tid = *tid;
679 switch(sizeof(u.tid)) {
680 case sizeof(apr_int32_t):
681 return conv_p2(*(apr_uint32_t *)&u.tid, 4, 'x', buf_end, len);
682 case sizeof(apr_int64_t):
683 return conv_p2_quad(*(apr_uint64_t *)&u.tid, 4, 'x', buf_end, len);
684 default:
685 /* not implemented; stick 0 in the buffer */
686 return conv_10(0, TRUE(!0), &is_negative, buf_end, len);
687 }
688}
689#endif
690
691/*
692 * Do format conversion placing the output in buffer
693 */
694APR_DECLARE(int)int apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *),
695 apr_vformatter_buff_t *vbuff, const char *fmt, va_list ap)
696{
697 register char *sp;
698 register char *bep;
699 register int cc = 0;
700 register apr_size_t i;
701
702 register char *s = NULL((void*)0);
703 char *q;
704 apr_size_t s_len;
705
706 register apr_size_t min_width = 0;
707 apr_size_t precision = 0;
708 enum {
709 LEFT, RIGHT
710 } adjust;
711 char pad_char;
712 char prefix_char;
713
714 double fp_num;
715 widest_int i_quad = (widest_int) 0;
716 u_widest_int ui_quad;
717 wide_int i_num = (wide_int) 0;
718 u_wide_int ui_num;
719
720 char num_buf[NUM_BUF_SIZE512];
721 char char_buf[2]; /* for printing %% and %<unknown> */
722
723 enum var_type_enum {
724 IS_QUAD, IS_LONG, IS_SHORT, IS_INT
725 };
726 enum var_type_enum var_type = IS_INT;
727
728 /*
729 * Flag variables
730 */
731 boolean_e alternate_form;
732 boolean_e print_sign;
733 boolean_e print_blank;
734 boolean_e adjust_precision;
735 boolean_e adjust_width;
736 bool_int is_negative;
737
738 sp = vbuff->curpos;
739 bep = vbuff->endpos;
740
741 while (*fmt) {
1
Loop condition is true. Entering loop body
13
Loop condition is true. Entering loop body
28
Loop condition is true. Entering loop body
742 if (*fmt != '%') {
2
Taking false branch
14
Taking false branch
29
Taking false branch
743 INS_CHAR(*fmt, sp, bep, cc){ if (sp) { if (sp >= bep) { vbuff->curpos = sp; if (flush_func
(vbuff)) return -1; sp = vbuff->curpos; bep = vbuff->endpos
; } *sp++ = (*fmt); } cc++; }
;
744 }
745 else {
746 /*
747 * Default variable settings
748 */
749 boolean_e print_something = YES;
750 adjust = RIGHT;
751 alternate_form = print_sign = print_blank = NO;
752 pad_char = ' ';
753 prefix_char = NUL'\0';
754
755 fmt++;
756
757 /*
758 * Try to avoid checking for flags, width or precision
759 */
760 if (!apr_islower(*fmt)(((*__ctype_b_loc ())[(int) ((((unsigned char)(*fmt))))] &
(unsigned short int) _ISlower))
) {
3
Taking false branch
15
Taking false branch
30
Taking false branch
761 /*
762 * Recognize flags: -, #, BLANK, +
763 */
764 for (;; fmt++) {
765 if (*fmt == '-')
766 adjust = LEFT;
767 else if (*fmt == '+')
768 print_sign = YES;
769 else if (*fmt == '#')
770 alternate_form = YES;
771 else if (*fmt == ' ')
772 print_blank = YES;
773 else if (*fmt == '0')
774 pad_char = '0';
775 else
776 break;
777 }
778
779 /*
780 * Check if a width was specified
781 */
782 if (apr_isdigit(*fmt)(((*__ctype_b_loc ())[(int) ((((unsigned char)(*fmt))))] &
(unsigned short int) _ISdigit))
) {
783 STR_TO_DEC(fmt, min_width)min_width = (*fmt++ - '0'); while ((((*__ctype_b_loc ())[(int
) ((((unsigned char)(*fmt))))] & (unsigned short int) _ISdigit
))) { min_width *= 10 ; min_width += (*fmt++ - '0'); }
;
784 adjust_width = YES;
785 }
786 else if (*fmt == '*') {
787 int v = va_arg(ap, int)__builtin_va_arg(ap, int);
788 fmt++;
789 adjust_width = YES;
790 if (v < 0) {
791 adjust = LEFT;
792 min_width = (apr_size_t)(-v);
793 }
794 else
795 min_width = (apr_size_t)v;
796 }
797 else
798 adjust_width = NO;
799
800 /*
801 * Check if a precision was specified
802 */
803 if (*fmt == '.') {
804 adjust_precision = YES;
805 fmt++;
806 if (apr_isdigit(*fmt)(((*__ctype_b_loc ())[(int) ((((unsigned char)(*fmt))))] &
(unsigned short int) _ISdigit))
) {
807 STR_TO_DEC(fmt, precision)precision = (*fmt++ - '0'); while ((((*__ctype_b_loc ())[(int
) ((((unsigned char)(*fmt))))] & (unsigned short int) _ISdigit
))) { precision *= 10 ; precision += (*fmt++ - '0'); }
;
808 }
809 else if (*fmt == '*') {
810 int v = va_arg(ap, int)__builtin_va_arg(ap, int);
811 fmt++;
812 precision = (v < 0) ? 0 : (apr_size_t)v;
813 }
814 else
815 precision = 0;
816 }
817 else
818 adjust_precision = NO;
819 }
820 else
821 adjust_precision = adjust_width = NO;
822
823 /*
824 * Modifier check. Note that if APR_INT64_T_FMT is "d",
825 * the first if condition is never true.
826 */
827
828 /* HACK BY FREESWITCH TEAM TO FIX COMPATIBILITY 2010-09-27 */
829 if (*fmt == 'l' && *(fmt + 1) == 'l') {
830 var_type = IS_QUAD;
831 fmt += 2;
832 }
833 else if ((sizeof(APR_INT64_T_FMT"ld") == 4 &&
834 fmt[0] == APR_INT64_T_FMT"ld"[0] &&
835 fmt[1] == APR_INT64_T_FMT"ld"[1]) ||
836 (sizeof(APR_INT64_T_FMT"ld") == 3 &&
837 fmt[0] == APR_INT64_T_FMT"ld"[0]) ||
838 (sizeof(APR_INT64_T_FMT"ld") > 4 &&
839 strncmp(fmt, APR_INT64_T_FMT,(__extension__ (__builtin_constant_p (sizeof("ld") - 2) &&
((__builtin_constant_p (fmt) && strlen (fmt) < ((
size_t) (sizeof("ld") - 2))) || (__builtin_constant_p ("ld") &&
strlen ("ld") < ((size_t) (sizeof("ld") - 2)))) ? __extension__
({ size_t __s1_len, __s2_len; (__builtin_constant_p (fmt) &&
__builtin_constant_p ("ld") && (__s1_len = __builtin_strlen
(fmt), __s2_len = __builtin_strlen ("ld"), (!((size_t)(const
void *)((fmt) + 1) - (size_t)(const void *)(fmt) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)(("ld") + 1) - (
size_t)(const void *)("ld") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(fmt, "ld") : (__builtin_constant_p (fmt) && ((size_t
)(const void *)((fmt) + 1) - (size_t)(const void *)(fmt) == 1
) && (__s1_len = __builtin_strlen (fmt), __s1_len <
4) ? (__builtin_constant_p ("ld") && ((size_t)(const
void *)(("ld") + 1) - (size_t)(const void *)("ld") == 1) ? __builtin_strcmp
(fmt, "ld") : (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) ("ld"); int __result = (
((const unsigned char *) (const char *) (fmt))[0] - __s2[0]);
if (__s1_len > 0 && __result == 0) { __result = (
((const unsigned char *) (const char *) (fmt))[1] - __s2[1]);
if (__s1_len > 1 && __result == 0) { __result = (
((const unsigned char *) (const char *) (fmt))[2] - __s2[2]);
if (__s1_len > 2 && __result == 0) __result = (((
const unsigned char *) (const char *) (fmt))[3] - __s2[3]); }
} __result; }))) : (__builtin_constant_p ("ld") && (
(size_t)(const void *)(("ld") + 1) - (size_t)(const void *)("ld"
) == 1) && (__s2_len = __builtin_strlen ("ld"), __s2_len
< 4) ? (__builtin_constant_p (fmt) && ((size_t)(const
void *)((fmt) + 1) - (size_t)(const void *)(fmt) == 1) ? __builtin_strcmp
(fmt, "ld") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (fmt); int __result
= (((const unsigned char *) (const char *) ("ld"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("ld"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("ld"))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) ("ld"))[3] - __s2[3
]); } } __result; })))) : __builtin_strcmp (fmt, "ld")))); })
: strncmp (fmt, "ld", sizeof("ld") - 2)))
840 sizeof(APR_INT64_T_FMT) - 2)(__extension__ (__builtin_constant_p (sizeof("ld") - 2) &&
((__builtin_constant_p (fmt) && strlen (fmt) < ((
size_t) (sizeof("ld") - 2))) || (__builtin_constant_p ("ld") &&
strlen ("ld") < ((size_t) (sizeof("ld") - 2)))) ? __extension__
({ size_t __s1_len, __s2_len; (__builtin_constant_p (fmt) &&
__builtin_constant_p ("ld") && (__s1_len = __builtin_strlen
(fmt), __s2_len = __builtin_strlen ("ld"), (!((size_t)(const
void *)((fmt) + 1) - (size_t)(const void *)(fmt) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)(("ld") + 1) - (
size_t)(const void *)("ld") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(fmt, "ld") : (__builtin_constant_p (fmt) && ((size_t
)(const void *)((fmt) + 1) - (size_t)(const void *)(fmt) == 1
) && (__s1_len = __builtin_strlen (fmt), __s1_len <
4) ? (__builtin_constant_p ("ld") && ((size_t)(const
void *)(("ld") + 1) - (size_t)(const void *)("ld") == 1) ? __builtin_strcmp
(fmt, "ld") : (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) ("ld"); int __result = (
((const unsigned char *) (const char *) (fmt))[0] - __s2[0]);
if (__s1_len > 0 && __result == 0) { __result = (
((const unsigned char *) (const char *) (fmt))[1] - __s2[1]);
if (__s1_len > 1 && __result == 0) { __result = (
((const unsigned char *) (const char *) (fmt))[2] - __s2[2]);
if (__s1_len > 2 && __result == 0) __result = (((
const unsigned char *) (const char *) (fmt))[3] - __s2[3]); }
} __result; }))) : (__builtin_constant_p ("ld") && (
(size_t)(const void *)(("ld") + 1) - (size_t)(const void *)("ld"
) == 1) && (__s2_len = __builtin_strlen ("ld"), __s2_len
< 4) ? (__builtin_constant_p (fmt) && ((size_t)(const
void *)((fmt) + 1) - (size_t)(const void *)(fmt) == 1) ? __builtin_strcmp
(fmt, "ld") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (fmt); int __result
= (((const unsigned char *) (const char *) ("ld"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("ld"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("ld"))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) ("ld"))[3] - __s2[3
]); } } __result; })))) : __builtin_strcmp (fmt, "ld")))); })
: strncmp (fmt, "ld", sizeof("ld") - 2)))
== 0)) {
841 /* Need to account for trailing 'd' and null in sizeof() */
842 var_type = IS_QUAD;
843 fmt += (sizeof(APR_INT64_T_FMT"ld") - 2);
844 }
845 else if (*fmt == 'q') {
4
Taking false branch
16
Taking false branch
31
Taking false branch
846 var_type = IS_QUAD;
847 fmt++;
848 }
849 else if (*fmt == 'l') {
5
Taking false branch
17
Taking false branch
32
Taking false branch
850 var_type = IS_LONG;
851 fmt++;
852 /* HACK BY FREESWITCH TEAM TO FIX COMPATIBILITY 2010-09-27 */
853 if (*fmt == 'l') {
854 var_type = IS_QUAD;
855 fmt++;
856 }
857 }
858 else if (*fmt == 'h') {
6
Taking false branch
18
Taking false branch
33
Taking false branch
859 var_type = IS_SHORT;
860 fmt++;
861 }
862 else {
863 var_type = IS_INT;
864 }
865
866 /*
867 * Argument extraction and printing.
868 * First we determine the argument type.
869 * Then, we convert the argument to a string.
870 * On exit from the switch, s points to the string that
871 * must be printed, s_len has the length of the string
872 * The precision requirements, if any, are reflected in s_len.
873 *
874 * NOTE: pad_char may be set to '0' because of the 0 flag.
875 * It is reset to ' ' by non-numeric formats
876 */
877 switch (*fmt) {
7
Control jumps to the 'default' case at line 1263
19
Control jumps to 'case 112:' at line 1114
34
Control jumps to 'case 112:' at line 1114
878 case 'u':
879 if (var_type == IS_QUAD) {
880 i_quad = va_arg(ap, u_widest_int)__builtin_va_arg(ap, u_widest_int);
881 s = conv_10_quad(i_quad, 1, &is_negative,
882 &num_buf[NUM_BUF_SIZE512], &s_len);
883 }
884 else {
885 if (var_type == IS_LONG)
886 i_num = (wide_int) va_arg(ap, u_wide_int)__builtin_va_arg(ap, u_wide_int);
887 else if (var_type == IS_SHORT)
888 i_num = (wide_int) (unsigned short) va_arg(ap, unsigned int)__builtin_va_arg(ap, unsigned int);
889 else
890 i_num = (wide_int) va_arg(ap, unsigned int)__builtin_va_arg(ap, unsigned int);
891 s = conv_10(i_num, 1, &is_negative,
892 &num_buf[NUM_BUF_SIZE512], &s_len);
893 }
894 FIX_PRECISION(adjust_precision, precision, s, s_len)if (adjust_precision) { apr_size_t p = (precision + 1 < 512
) ? precision : 512 - 1; while (s_len < p) { *--s = '0'; s_len
++; } }
;
895 break;
896
897 case 'd':
898 case 'i':
899 if (var_type == IS_QUAD) {
900 i_quad = va_arg(ap, widest_int)__builtin_va_arg(ap, widest_int);
901 s = conv_10_quad(i_quad, 0, &is_negative,
902 &num_buf[NUM_BUF_SIZE512], &s_len);
903 }
904 else {
905 if (var_type == IS_LONG)
906 i_num = (wide_int) va_arg(ap, wide_int)__builtin_va_arg(ap, wide_int);
907 else if (var_type == IS_SHORT)
908 i_num = (wide_int) (short) va_arg(ap, int)__builtin_va_arg(ap, int);
909 else
910 i_num = (wide_int) va_arg(ap, int)__builtin_va_arg(ap, int);
911 s = conv_10(i_num, 0, &is_negative,
912 &num_buf[NUM_BUF_SIZE512], &s_len);
913 }
914 FIX_PRECISION(adjust_precision, precision, s, s_len)if (adjust_precision) { apr_size_t p = (precision + 1 < 512
) ? precision : 512 - 1; while (s_len < p) { *--s = '0'; s_len
++; } }
;
915
916 if (is_negative)
917 prefix_char = '-';
918 else if (print_sign)
919 prefix_char = '+';
920 else if (print_blank)
921 prefix_char = ' ';
922 break;
923
924
925 case 'o':
926 if (var_type == IS_QUAD) {
927 ui_quad = va_arg(ap, u_widest_int)__builtin_va_arg(ap, u_widest_int);
928 s = conv_p2_quad(ui_quad, 3, *fmt,
929 &num_buf[NUM_BUF_SIZE512], &s_len);
930 }
931 else {
932 if (var_type == IS_LONG)
933 ui_num = (u_wide_int) va_arg(ap, u_wide_int)__builtin_va_arg(ap, u_wide_int);
934 else if (var_type == IS_SHORT)
935 ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int)__builtin_va_arg(ap, unsigned int);
936 else
937 ui_num = (u_wide_int) va_arg(ap, unsigned int)__builtin_va_arg(ap, unsigned int);
938 s = conv_p2(ui_num, 3, *fmt,
939 &num_buf[NUM_BUF_SIZE512], &s_len);
940 }
941 FIX_PRECISION(adjust_precision, precision, s, s_len)if (adjust_precision) { apr_size_t p = (precision + 1 < 512
) ? precision : 512 - 1; while (s_len < p) { *--s = '0'; s_len
++; } }
;
942 if (alternate_form && *s != '0') {
943 *--s = '0';
944 s_len++;
945 }
946 break;
947
948
949 case 'x':
950 case 'X':
951 if (var_type == IS_QUAD) {
952 ui_quad = va_arg(ap, u_widest_int)__builtin_va_arg(ap, u_widest_int);
953 s = conv_p2_quad(ui_quad, 4, *fmt,
954 &num_buf[NUM_BUF_SIZE512], &s_len);
955 }
956 else {
957 if (var_type == IS_LONG)
958 ui_num = (u_wide_int) va_arg(ap, u_wide_int)__builtin_va_arg(ap, u_wide_int);
959 else if (var_type == IS_SHORT)
960 ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int)__builtin_va_arg(ap, unsigned int);
961 else
962 ui_num = (u_wide_int) va_arg(ap, unsigned int)__builtin_va_arg(ap, unsigned int);
963 s = conv_p2(ui_num, 4, *fmt,
964 &num_buf[NUM_BUF_SIZE512], &s_len);
965 }
966 FIX_PRECISION(adjust_precision, precision, s, s_len)if (adjust_precision) { apr_size_t p = (precision + 1 < 512
) ? precision : 512 - 1; while (s_len < p) { *--s = '0'; s_len
++; } }
;
967 if (alternate_form && i_num != 0) {
968 *--s = *fmt; /* 'x' or 'X' */
969 *--s = '0';
970 s_len += 2;
971 }
972 break;
973
974
975 case 's':
976 s = va_arg(ap, char *)__builtin_va_arg(ap, char *);
977 if (s != NULL((void*)0)) {
978 if (!adjust_precision) {
979 s_len = strlen(s);
980 }
981 else {
982 /* From the C library standard in section 7.9.6.1:
983 * ...if the precision is specified, no more then
984 * that many characters are written. If the
985 * precision is not specified or is greater
986 * than the size of the array, the array shall
987 * contain a null character.
988 *
989 * My reading is is precision is specified and
990 * is less then or equal to the size of the
991 * array, no null character is required. So
992 * we can't do a strlen.
993 *
994 * This figures out the length of the string
995 * up to the precision. Once it's long enough
996 * for the specified precision, we don't care
997 * anymore.
998 *
999 * NOTE: you must do the length comparison
1000 * before the check for the null character.
1001 * Otherwise, you'll check one beyond the
1002 * last valid character.
1003 */
1004 const char *walk;
1005
1006 for (walk = s, s_len = 0;
1007 (s_len < precision) && (*walk != '\0');
1008 ++walk, ++s_len);
1009 }
1010 }
1011 else {
1012 s = S_NULL"(null)";
1013 s_len = S_NULL_LEN6;
1014 }
1015 pad_char = ' ';
1016 break;
1017
1018
1019 case 'f':
1020 case 'e':
1021 case 'E':
1022 fp_num = va_arg(ap, double)__builtin_va_arg(ap, double);
1023 /*
1024 * We use &num_buf[ 1 ], so that we have room for the sign
1025 */
1026 s = NULL((void*)0);
1027#ifdef HAVE_ISNAN1
1028 if (isnan(fp_num)(sizeof (fp_num) == sizeof (float) ? __isnanf (fp_num) : sizeof
(fp_num) == sizeof (double) ? __isnan (fp_num) : __isnanl (fp_num
))
) {
1029 s = "nan";
1030 s_len = 3;
1031 }
1032#endif
1033#ifdef HAVE_ISINF1
1034 if (!s && isinf(fp_num)(sizeof (fp_num) == sizeof (float) ? __isinff (fp_num) : sizeof
(fp_num) == sizeof (double) ? __isinf (fp_num) : __isinfl (fp_num
))
) {
1035 s = "inf";
1036 s_len = 3;
1037 }
1038#endif
1039 if (!s) {
1040 s = conv_fp(*fmt, fp_num, alternate_form,
1041 (adjust_precision == NO) ? FLOAT_DIGITS6 : precision,
1042 &is_negative, &num_buf[1], &s_len);
1043 if (is_negative)
1044 prefix_char = '-';
1045 else if (print_sign)
1046 prefix_char = '+';
1047 else if (print_blank)
1048 prefix_char = ' ';
1049 }
1050 break;
1051
1052
1053 case 'g':
1054 case 'G':
1055 if (adjust_precision == NO)
1056 precision = FLOAT_DIGITS6;
1057 else if (precision == 0)
1058 precision = 1;
1059 /*
1060 * * We use &num_buf[ 1 ], so that we have room for the sign
1061 */
1062 s = apr_gcvt(va_arg(ap, double)__builtin_va_arg(ap, double), precision, &num_buf[1],
1063 alternate_form);
1064 if (*s == '-')
1065 prefix_char = *s++;
1066 else if (print_sign)
1067 prefix_char = '+';
1068 else if (print_blank)
1069 prefix_char = ' ';
1070
1071 s_len = strlen(s);
1072
1073 if (alternate_form && (q = strchr(s, '.')(__extension__ (__builtin_constant_p ('.') && !__builtin_constant_p
(s) && ('.') == '\0' ? (char *) __rawmemchr (s, '.')
: __builtin_strchr (s, '.')))
) == NULL((void*)0)) {
1074 s[s_len++] = '.';
1075 s[s_len] = '\0'; /* delimit for following strchr() */
1076 }
1077 if (*fmt == 'G' && (q = strchr(s, 'e')(__extension__ (__builtin_constant_p ('e') && !__builtin_constant_p
(s) && ('e') == '\0' ? (char *) __rawmemchr (s, 'e')
: __builtin_strchr (s, 'e')))
) != NULL((void*)0))
1078 *q = 'E';
1079 break;
1080
1081
1082 case 'c':
1083 char_buf[0] = (char) (va_arg(ap, int)__builtin_va_arg(ap, int));
1084 s = &char_buf[0];
1085 s_len = 1;
1086 pad_char = ' ';
1087 break;
1088
1089
1090 case '%':
1091 char_buf[0] = '%';
1092 s = &char_buf[0];
1093 s_len = 1;
1094 pad_char = ' ';
1095 break;
1096
1097
1098 case 'n':
1099 if (var_type == IS_QUAD)
1100 *(va_arg(ap, widest_int *)__builtin_va_arg(ap, widest_int *)) = cc;
1101 else if (var_type == IS_LONG)
1102 *(va_arg(ap, long *)__builtin_va_arg(ap, long *)) = cc;
1103 else if (var_type == IS_SHORT)
1104 *(va_arg(ap, short *)__builtin_va_arg(ap, short *)) = cc;
1105 else
1106 *(va_arg(ap, int *)__builtin_va_arg(ap, int *)) = cc;
1107 print_something = NO;
1108 break;
1109
1110 /*
1111 * This is where we extend the printf format, with a second
1112 * type specifier
1113 */
1114 case 'p':
1115 switch(*++fmt) {
20
Control jumps to 'case 116:' at line 1207
35
Control jumps to 'case 84:' at line 1182
1116 /*
1117 * If the pointer size is equal to or smaller than the size
1118 * of the largest unsigned int, we convert the pointer to a
1119 * hex number, otherwise we print "%p" to indicate that we
1120 * don't handle "%p".
1121 */
1122 case 'p':
1123#ifdef APR_VOID_P_IS_QUAD
1124 if (sizeof(void *) <= sizeof(u_widest_int)) {
1125 ui_quad = (u_widest_int) va_arg(ap, void *)__builtin_va_arg(ap, void *);
1126 s = conv_p2_quad(ui_quad, 4, 'x',
1127 &num_buf[NUM_BUF_SIZE512], &s_len);
1128 }
1129#else
1130 if (sizeof(void *) <= sizeof(u_wide_int)) {
1131 ui_num = (u_wide_int) va_arg(ap, void *)__builtin_va_arg(ap, void *);
1132 s = conv_p2(ui_num, 4, 'x',
1133 &num_buf[NUM_BUF_SIZE512], &s_len);
1134 }
1135#endif
1136 else {
1137 s = "%p";
1138 s_len = 2;
1139 prefix_char = NUL'\0';
1140 }
1141 pad_char = ' ';
1142 break;
1143
1144 /* print an apr_sockaddr_t as a.b.c.d:port */
1145 case 'I':
1146 {
1147 apr_sockaddr_t *sa;
1148
1149 sa = va_arg(ap, apr_sockaddr_t *)__builtin_va_arg(ap, apr_sockaddr_t *);
1150 if (sa != NULL((void*)0)) {
1151 s = conv_apr_sockaddr(sa, &num_buf[NUM_BUF_SIZE512], &s_len);
1152 if (adjust_precision && precision < s_len)
1153 s_len = precision;
1154 }
1155 else {
1156 s = S_NULL"(null)";
1157 s_len = S_NULL_LEN6;
1158 }
1159 pad_char = ' ';
1160 }
1161 break;
1162
1163 /* print a struct in_addr as a.b.c.d */
1164 case 'A':
1165 {
1166 struct in_addr *ia;
1167
1168 ia = va_arg(ap, struct in_addr *)__builtin_va_arg(ap, struct in_addr *);
1169 if (ia != NULL((void*)0)) {
1170 s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE512], &s_len);
1171 if (adjust_precision && precision < s_len)
1172 s_len = precision;
1173 }
1174 else {
1175 s = S_NULL"(null)";
1176 s_len = S_NULL_LEN6;
1177 }
1178 pad_char = ' ';
1179 }
1180 break;
1181
1182 case 'T':
1183#if APR_HAS_THREADS1
1184 {
1185 apr_os_thread_t *tid;
1186
1187 tid = va_arg(ap, apr_os_thread_t *)__builtin_va_arg(ap, apr_os_thread_t *);
1188 if (tid != NULL((void*)0)) {
36
Assuming 'tid' is not equal to null
37
Taking true branch
1189 s = conv_os_thread_t(tid, &num_buf[NUM_BUF_SIZE512], &s_len);
38
Calling 'conv_os_thread_t'
1190 if (adjust_precision && precision < s_len)
1191 s_len = precision;
1192 }
1193 else {
1194 s = S_NULL"(null)";
1195 s_len = S_NULL_LEN6;
1196 }
1197 pad_char = ' ';
1198 }
1199#else
1200 char_buf[0] = '0';
1201 s = &char_buf[0];
1202 s_len = 1;
1203 pad_char = ' ';
1204#endif
1205 break;
1206
1207 case 't':
1208#if APR_HAS_THREADS1
1209 {
1210 apr_os_thread_t *tid;
1211
1212 tid = va_arg(ap, apr_os_thread_t *)__builtin_va_arg(ap, apr_os_thread_t *);
1213 if (tid != NULL((void*)0)) {
21
Assuming 'tid' is not equal to null
22
Taking true branch
1214 s = conv_os_thread_t_hex(tid, &num_buf[NUM_BUF_SIZE512], &s_len);
1215 if (adjust_precision && precision < s_len)
1216 s_len = precision;
1217 }
1218 else {
1219 s = S_NULL"(null)";
1220 s_len = S_NULL_LEN6;
1221 }
1222 pad_char = ' ';
1223 }
1224#else
1225 char_buf[0] = '0';
1226 s = &char_buf[0];
1227 s_len = 1;
1228 pad_char = ' ';
1229#endif
1230 break;
23
Execution continues on line 1243
1231
1232 case NUL'\0':
1233 /* if %p ends the string, oh well ignore it */
1234 continue;
1235
1236 default:
1237 s = "bogus %p";
1238 s_len = 8;
1239 prefix_char = NUL'\0';
1240 (void)va_arg(ap, void *)__builtin_va_arg(ap, void *); /* skip the bogus argument on the stack */
1241 break;
1242 }
1243 break;
24
Execution continues on line 1272
1244
1245 case NUL'\0':
1246 /*
1247 * The last character of the format string was %.
1248 * We ignore it.
1249 */
1250 continue;
1251
1252
1253 /*
1254 * The default case is for unrecognized %'s.
1255 * We print %<char> to help the user identify what
1256 * option is not understood.
1257 * This is also useful in case the user wants to pass
1258 * the output of format_converter to another function
1259 * that understands some other %<char> (like syslog).
1260 * Note that we can't point s inside fmt because the
1261 * unknown <char> could be preceded by width etc.
1262 */
1263 default:
1264 char_buf[0] = '%';
1265 char_buf[1] = *fmt;
1266 s = char_buf;
1267 s_len = 2;
1268 pad_char = ' ';
1269 break;
8
Execution continues on line 1272
1270 }
1271
1272 if (prefix_char != NUL'\0' && s != S_NULL"(null)" && s != char_buf) {
1273 *--s = prefix_char;
1274 s_len++;
1275 }
1276
1277 if (adjust_width && adjust == RIGHT && min_width > s_len) {
1278 if (pad_char == '0' && prefix_char != NUL'\0') {
1279 INS_CHAR(*s, sp, bep, cc){ if (sp) { if (sp >= bep) { vbuff->curpos = sp; if (flush_func
(vbuff)) return -1; sp = vbuff->curpos; bep = vbuff->endpos
; } *sp++ = (*s); } cc++; }
;
1280 s++;
1281 s_len--;
1282 min_width--;
1283 }
1284 PAD(min_width, s_len, pad_char)do { { if (sp) { if (sp >= bep) { vbuff->curpos = sp; if
(flush_func(vbuff)) return -1; sp = vbuff->curpos; bep = vbuff
->endpos; } *sp++ = (pad_char); } cc++; }; min_width--; } while
(min_width > s_len)
;
1285 }
1286
1287 /*
1288 * Print the string s.
1289 */
1290 if (print_something == YES) {
9
Taking true branch
25
Taking true branch
1291 for (i = s_len; i != 0; i--) {
10
Loop condition is true. Entering loop body
11
Loop condition is true. Entering loop body
12
Loop condition is false. Execution continues on line 1297
26
Assuming 'i' is equal to 0
27
Loop condition is false. Execution continues on line 1297
1292 INS_CHAR(*s, sp, bep, cc){ if (sp) { if (sp >= bep) { vbuff->curpos = sp; if (flush_func
(vbuff)) return -1; sp = vbuff->curpos; bep = vbuff->endpos
; } *sp++ = (*s); } cc++; }
;
1293 s++;
1294 }
1295 }
1296
1297 if (adjust_width && adjust == LEFT && min_width > s_len)
1298 PAD(min_width, s_len, pad_char)do { { if (sp) { if (sp >= bep) { vbuff->curpos = sp; if
(flush_func(vbuff)) return -1; sp = vbuff->curpos; bep = vbuff
->endpos; } *sp++ = (pad_char); } cc++; }; min_width--; } while
(min_width > s_len)
;
1299 }
1300 fmt++;
1301 }
1302 vbuff->curpos = sp;
1303
1304 return cc;
1305}
1306
1307
1308static int snprintf_flush(apr_vformatter_buff_t *vbuff)
1309{
1310 /* if the buffer fills we have to abort immediately, there is no way
1311 * to "flush" an apr_snprintf... there's nowhere to flush it to.
1312 */
1313 return -1;
1314}
1315
1316
1317APR_DECLARE_NONSTD(int)int apr_snprintf(char *buf, apr_size_t len,
1318 const char *format, ...)
1319{
1320 int cc;
1321 va_list ap;
1322 apr_vformatter_buff_t vbuff;
1323
1324 if (len == 0) {
1325 /* NOTE: This is a special case; we just want to return the number
1326 * of chars that would be written (minus \0) if the buffer
1327 * size was infinite. We leverage the fact that INS_CHAR
1328 * just does actual inserts iff the buffer pointer is non-NULL.
1329 * In this case, we don't care what buf is; it can be NULL, since
1330 * we don't touch it at all.
1331 */
1332 vbuff.curpos = NULL((void*)0);
1333 vbuff.endpos = NULL((void*)0);
1334 } else {
1335 /* save one byte for nul terminator */
1336 vbuff.curpos = buf;
1337 vbuff.endpos = buf + len - 1;
1338 }
1339 va_start(ap, format)__builtin_va_start(ap, format);
1340 cc = apr_vformatter(snprintf_flush, &vbuff, format, ap);
1341 va_end(ap)__builtin_va_end(ap);
1342 if (len != 0) {
1343 *vbuff.curpos = '\0';
1344 }
1345 return (cc == -1) ? (int)len - 1 : cc;
1346}
1347
1348
1349APR_DECLARE(int)int apr_vsnprintf(char *buf, apr_size_t len, const char *format,
1350 va_list ap)
1351{
1352 int cc;
1353 apr_vformatter_buff_t vbuff;
1354
1355 if (len == 0) {
1356 /* See above note */
1357 vbuff.curpos = NULL((void*)0);
1358 vbuff.endpos = NULL((void*)0);
1359 } else {
1360 /* save one byte for nul terminator */
1361 vbuff.curpos = buf;
1362 vbuff.endpos = buf + len - 1;
1363 }
1364 cc = apr_vformatter(snprintf_flush, &vbuff, format, ap);
1365 if (len != 0) {
1366 *vbuff.curpos = '\0';
1367 }
1368 return (cc == -1) ? (int)len - 1 : cc;
1369}