1 #include "stdio_impl.h"
2 #include <errno.h>
3 #include <ctype.h>
4 #include <limits.h>
5 #include <string.h>
6 #include <stdarg.h>
7 #include <stddef.h>
8 #include <stdlib.h>
9 #include <wchar.h>
10 #include <inttypes.h>
11 #include <math.h>
12 #include <float.h>
13 
14 /*
15  * TRUSTY - long doubles are 128 bits on ARM 64, which drastically increases
16  * stack size and requires software emulation. To save resources, allow programs
17  * to specify the largest floating point type they will print with STDIO_FLOAT.
18  *    0: disabled
19  *   32: float
20  *   64: double
21  *  128: long double
22  * This is a bit of a lie. long doubles are not always 128 bits. This
23  * preprocessor does not make it easy to do this symbolically, however, so we
24  * lie.
25  */
26 
27 /* Default */
28 #ifndef STDIO_FLOAT
29 #define STDIO_FLOAT 0
30 #endif
31 
32 /* Sanity check. */
33 #if STDIO_FLOAT != 0 && STDIO_FLOAT != 32 && STDIO_FLOAT != 64 && STDIO_FLOAT != 128
34 #error Invalid STDIO_FLOAT
35 #endif
36 
37 /* Define these names in all cases, even if STDIO_FLOAT is invalid. */
38 #if STDIO_FLOAT == 32
39 typedef float stdio_float;
40 #define STDIO_EPSILON FLT_EPSILON
41 #define STDIO_FREXP frexpf
42 #define STDIO_MAX_EXP FLT_MAX_EXP
43 #define STDIO_MANT_DIG FLT_MANT_DIG
44 #elif STDIO_FLOAT == 128
45 typedef long double stdio_float;
46 #define STDIO_EPSILON LDBL_EPSILON
47 #define STDIO_FREXP frexpl
48 #define STDIO_MAX_EXP LDBL_MAX_EXP
49 #define STDIO_MANT_DIG LDBL_MANT_DIG
50 #else
51 typedef double stdio_float;
52 #define STDIO_EPSILON DBL_EPSILON
53 #define STDIO_FREXP frexp
54 #define STDIO_MAX_EXP DBL_MAX_EXP
55 #define STDIO_MANT_DIG DBL_MANT_DIG
56 #endif
57 
58 /* TRUSTY - GNU extention that calls stderr, which can increase rodata size. */
59 #ifndef STDIO_NO_FORMAT_M
60 #define STDIO_NO_FORMAT_M 1
61 #endif
62 
63 /* TRUSTY - Nonstandard wide character formatting. */
64 #ifndef STDIO_NO_FORMAT_WIDE
65 #define STDIO_NO_FORMAT_WIDE 1
66 #endif
67 
68 /* Some useful macros */
69 
70 #ifndef MAX
71 #define MAX(a,b) ((a)>(b) ? (a) : (b))
72 #endif
73 #ifndef MIN
74 #define MIN(a,b) ((a)<(b) ? (a) : (b))
75 #endif
76 
77 /*
78  * TRUSTY - Macro used to determine if an integer number should
79  * not be printed.
80  */
81 #define NUMBER_IN_FILTER_RANGE(num) (((num) > 4096) && ((num) < (uintptr_t)-4096))
82 
83 /* Convenient bit representation for modifier flags, which all fall
84  * within 31 codepoints of the space character. */
85 
86 #define ALT_FORM   (1U<<'#'-' ')
87 #define ZERO_PAD   (1U<<'0'-' ')
88 #define LEFT_ADJ   (1U<<'-'-' ')
89 #define PAD_POS    (1U<<' '-' ')
90 #define MARK_POS   (1U<<'+'-' ')
91 #define GROUPED    (1U<<'\''-' ')
92 
93 #define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
94 
95 /* State machine to accept length modifiers + conversion specifiers.
96  * Result is 0 on failure, or an argument type to pop on success. */
97 
98 enum {
99 	BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
100 	ZTPRE, JPRE,
101 	STOP,
102 	PTR, INT, UINT, ULLONG,
103 	LONG, ULONG,
104 	SHORT, USHORT, CHAR, UCHAR,
105 	LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
106 	DBL, LDBL,
107 	NOARG,
108 	MAXSTATE
109 };
110 
111 #define S(x) [(x)-'A']
112 
113 static const unsigned char states[]['z'-'A'+1] = {
114 	{ /* 0: bare types */
115 		S('d') = INT, S('i') = INT,
116 		S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
117 		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
118 		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
119 		S('c') = CHAR, S('C') = INT,
120 		S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
121 		S('m') = NOARG,
122 		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
123 		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
124 	}, { /* 1: l-prefixed */
125 		S('d') = LONG, S('i') = LONG,
126 		S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
127 		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
128 		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
129 		S('c') = INT, S('s') = PTR, S('n') = PTR,
130 		S('l') = LLPRE,
131 	}, { /* 2: ll-prefixed */
132 		S('d') = LLONG, S('i') = LLONG,
133 		S('o') = ULLONG, S('u') = ULLONG,
134 		S('x') = ULLONG, S('X') = ULLONG,
135 		S('n') = PTR,
136 	}, { /* 3: h-prefixed */
137 		S('d') = SHORT, S('i') = SHORT,
138 		S('o') = USHORT, S('u') = USHORT,
139 		S('x') = USHORT, S('X') = USHORT,
140 		S('n') = PTR,
141 		S('h') = HHPRE,
142 	}, { /* 4: hh-prefixed */
143 		S('d') = CHAR, S('i') = CHAR,
144 		S('o') = UCHAR, S('u') = UCHAR,
145 		S('x') = UCHAR, S('X') = UCHAR,
146 		S('n') = PTR,
147 	}, { /* 5: L-prefixed */
148 		S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
149 		S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
150 		S('n') = PTR,
151 	}, { /* 6: z- or t-prefixed (assumed to be same size) */
152 		S('d') = PDIFF, S('i') = PDIFF,
153 		S('o') = SIZET, S('u') = SIZET,
154 		S('x') = SIZET, S('X') = SIZET,
155 		S('n') = PTR,
156 	}, { /* 7: j-prefixed */
157 		S('d') = IMAX, S('i') = IMAX,
158 		S('o') = UMAX, S('u') = UMAX,
159 		S('x') = UMAX, S('X') = UMAX,
160 		S('n') = PTR,
161 	}
162 };
163 
164 #define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
165 
166 union arg
167 {
168 	uintmax_t i;
169 	stdio_float f;
170 	void *p;
171 };
172 
pop_arg(union arg * arg,int type,va_list * ap)173 static void pop_arg(union arg *arg, int type, va_list *ap)
174 {
175 	switch (type) {
176 	       case PTR:	arg->p = va_arg(*ap, void *);
177 	break; case INT:	arg->i = va_arg(*ap, int);
178 	break; case UINT:	arg->i = va_arg(*ap, unsigned int);
179 	break; case LONG:	arg->i = va_arg(*ap, long);
180 	break; case ULONG:	arg->i = va_arg(*ap, unsigned long);
181 	break; case ULLONG:	arg->i = va_arg(*ap, unsigned long long);
182 	break; case SHORT:	arg->i = (short)va_arg(*ap, int);
183 	break; case USHORT:	arg->i = (unsigned short)va_arg(*ap, int);
184 	break; case CHAR:	arg->i = (signed char)va_arg(*ap, int);
185 	break; case UCHAR:	arg->i = (unsigned char)va_arg(*ap, int);
186 	break; case LLONG:	arg->i = va_arg(*ap, long long);
187 	break; case SIZET:	arg->i = va_arg(*ap, size_t);
188 	break; case IMAX:	arg->i = va_arg(*ap, intmax_t);
189 	break; case UMAX:	arg->i = va_arg(*ap, uintmax_t);
190 	break; case PDIFF:	arg->i = va_arg(*ap, ptrdiff_t);
191 	break; case UIPTR:	arg->i = (uintptr_t)va_arg(*ap, void *);
192 #if !WITH_NO_FP
193 	break; case DBL:	arg->f = (stdio_float)va_arg(*ap, double);
194 #if STDIO_FLOAT == 128
195 	break; case LDBL:	arg->f = va_arg(*ap, long double);
196 #else
197         /* Zero out to avoid software conversion. */
198         break; case LDBL:	va_arg(*ap, long double); arg->f = 0;
199 #endif
200 #else
201 	break; default:		fputs("Floating point code is not supported\n", stderr);
202 				abort();
203 #endif // !WITH_NO_FP
204 	}
205 }
206 
out(FILE * f,const char * s,size_t l)207 static void out(FILE *f, const char *s, size_t l)
208 {
209 	if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f);
210 }
211 
pad(FILE * f,char c,int w,int l,int fl)212 static void pad(FILE *f, char c, int w, int l, int fl)
213 {
214 	char pad[256];
215 	if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
216 	l = w - l;
217 	memset(pad, c, l>sizeof pad ? sizeof pad : l);
218 	for (; l >= sizeof pad; l -= sizeof pad)
219 		out(f, pad, sizeof pad);
220 	out(f, pad, l);
221 }
222 
223 static const char xdigits[16] = {
224 	"0123456789ABCDEF"
225 };
226 
227 /*
228  * TRUSTY - This is the function used to return what will
229  * be printed if a number value shouldn't be shown.
230  */
fmt_filter(uintmax_t x,char * s)231 static char *fmt_filter(uintmax_t x, char *s)
232 {
233 	/* ignoring x value on this
234 	 * implementation, always
235 	 * filtering with ***.*/
236 	for (x = 0; x < 3; x++) *--s = '*';
237 	return s;
238 }
239 
fmt_x(uintmax_t x,char * s,int lower)240 static char *fmt_x(uintmax_t x, char *s, int lower)
241 {
242 	for (; x; x>>=4) *--s = xdigits[(x&15)]|lower;
243 	return s;
244 }
245 
fmt_o(uintmax_t x,char * s)246 static char *fmt_o(uintmax_t x, char *s)
247 {
248 	for (; x; x>>=3) *--s = '0' + (x&7);
249 	return s;
250 }
251 
fmt_u(uintmax_t x,char * s)252 static char *fmt_u(uintmax_t x, char *s)
253 {
254 	unsigned long y;
255 	for (   ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;
256 	for (y=x;           y; y/=10) *--s = '0' + y%10;
257 	return s;
258 }
259 
260 /* Do not override this check. The floating point printing code below
261  * depends on the float.h constants being right. If they are wrong, it
262  * may overflow the stack. */
263 #if LDBL_MANT_DIG == 53
264 typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)];
265 #endif
266 
267 #if !WITH_NO_FP
268 /* TRUSTY - noinline to save stack space when floats are not printed. */
269 __attribute__((__noinline__))
fmt_fp(FILE * f,stdio_float y,int w,int p,int fl,int t)270 static int fmt_fp(FILE *f, stdio_float y, int w, int p, int fl, int t)
271 {
272 	uint32_t big[(STDIO_MANT_DIG+28)/29 + 1          // mantissa expansion
273 		+ (STDIO_MAX_EXP+STDIO_MANT_DIG+28+8)/9]; // exponent expansion
274 	uint32_t *a, *d, *r, *z;
275 	int e2=0, e, i, j, l;
276 	char buf[9+STDIO_MANT_DIG/4], *s;
277 	const char *prefix="-0X+0X 0X-0x+0x 0x";
278 	int pl;
279 	char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
280 
281 	pl=1;
282 	if (signbit(y)) {
283 		y=-y;
284 	} else if (fl & MARK_POS) {
285 		prefix+=3;
286 	} else if (fl & PAD_POS) {
287 		prefix+=6;
288 	} else prefix++, pl=0;
289 
290 	if (!isfinite(y)) {
291 		char *s = (t&32)?"inf":"INF";
292 		if (y!=y) s=(t&32)?"nan":"NAN";
293 		pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
294 		out(f, prefix, pl);
295 		out(f, s, 3);
296 		pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
297 		return MAX(w, 3+pl);
298 	}
299 
300 	y = STDIO_FREXP(y, &e2) * 2;
301 	if (y) e2--;
302 
303 	if ((t|32)=='a') {
304 		stdio_float round = 8.0;
305 		int re;
306 
307 		if (t&32) prefix += 9;
308 		pl += 2;
309 
310 		if (p<0 || p>=STDIO_MANT_DIG/4-1) re=0;
311 		else re=STDIO_MANT_DIG/4-1-p;
312 
313 		if (re) {
314 			round *= 1<<(STDIO_MANT_DIG%4);
315 			while (re--) round*=16;
316 			if (*prefix=='-') {
317 				y=-y;
318 				y-=round;
319 				y+=round;
320 				y=-y;
321 			} else {
322 				y+=round;
323 				y-=round;
324 			}
325 		}
326 
327 		estr=fmt_u(e2<0 ? -e2 : e2, ebuf);
328 		if (estr==ebuf) *--estr='0';
329 		*--estr = (e2<0 ? '-' : '+');
330 		*--estr = t+('p'-'a');
331 
332 		s=buf;
333 		do {
334 			int x=y;
335 			*s++=xdigits[x]|(t&32);
336 			y=16*(y-x);
337 			if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';
338 		} while (y);
339 
340 		if (p > INT_MAX-2-(ebuf-estr)-pl)
341 			return -1;
342 		if (p && s-buf-2 < p)
343 			l = (p+2) + (ebuf-estr);
344 		else
345 			l = (s-buf) + (ebuf-estr);
346 
347 		pad(f, ' ', w, pl+l, fl);
348 		out(f, prefix, pl);
349 		pad(f, '0', w, pl+l, fl^ZERO_PAD);
350 		out(f, buf, s-buf);
351 		pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
352 		out(f, estr, ebuf-estr);
353 		pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
354 		return MAX(w, pl+l);
355 	}
356 	if (p<0) p=6;
357 
358 	if (y) y *= 0x1p28, e2-=28;
359 
360 	if (e2<0) a=r=z=big;
361 	else a=r=z=big+sizeof(big)/sizeof(*big) - STDIO_MANT_DIG - 1;
362 
363 	do {
364 		*z = y;
365 		y = 1000000000*(y-*z++);
366 	} while (y);
367 
368 	while (e2>0) {
369 		uint32_t carry=0;
370 		int sh=MIN(29,e2);
371 		for (d=z-1; d>=a; d--) {
372 			uint64_t x = ((uint64_t)*d<<sh)+carry;
373 			*d = x % 1000000000;
374 			carry = x / 1000000000;
375 		}
376 		if (carry) *--a = carry;
377 		while (z>a && !z[-1]) z--;
378 		e2-=sh;
379 	}
380 	while (e2<0) {
381 		uint32_t carry=0, *b;
382 		int sh=MIN(9,-e2), need=1+(p+STDIO_MANT_DIG/3U+8)/9;
383 		for (d=a; d<z; d++) {
384 			uint32_t rm = *d & (1<<sh)-1;
385 			*d = (*d>>sh) + carry;
386 			carry = (1000000000>>sh) * rm;
387 		}
388 		if (!*a) a++;
389 		if (carry) *z++ = carry;
390 		/* Avoid (slow!) computation past requested precision */
391 		b = (t|32)=='f' ? r : a;
392 		if (z-b > need) z = b+need;
393 		e2+=sh;
394 	}
395 
396 	if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
397 	else e=0;
398 
399 	/* Perform rounding: j is precision after the radix (possibly neg) */
400 	j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);
401 	if (j < 9*(z-r-1)) {
402 		uint32_t x;
403 		/* We avoid C's broken division of negative numbers */
404 		d = r + 1 + ((j+9*STDIO_MAX_EXP)/9 - STDIO_MAX_EXP);
405 		j += 9*STDIO_MAX_EXP;
406 		j %= 9;
407 		for (i=10, j++; j<9; i*=10, j++);
408 		x = *d % i;
409 		/* Are there any significant digits past j? */
410 		if (x || d+1!=z) {
411 			stdio_float round = 2/STDIO_EPSILON;
412 			stdio_float small;
413 			if ((*d/i & 1) || (i==1000000000 && d>a && (d[-1]&1)))
414 				round += 2;
415 			if (x<i/2) small=0x0.8p0;
416 			else if (x==i/2 && d+1==z) small=0x1.0p0;
417 			else small=0x1.8p0;
418 			if (pl && *prefix=='-') round*=-1, small*=-1;
419 			*d -= x;
420 			/* Decide whether to round by probing round+small */
421 			if (round+small != round) {
422 				*d = *d + i;
423 				while (*d > 999999999) {
424 					*d--=0;
425 					if (d<a) *--a=0;
426 					(*d)++;
427 				}
428 				for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
429 			}
430 		}
431 		if (z>d+1) z=d+1;
432 	}
433 	for (; z>a && !z[-1]; z--);
434 
435 	if ((t|32)=='g') {
436 		if (!p) p++;
437 		if (p>e && e>=-4) {
438 			t--;
439 			p-=e+1;
440 		} else {
441 			t-=2;
442 			p--;
443 		}
444 		if (!(fl&ALT_FORM)) {
445 			/* Count trailing zeros in last place */
446 			if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);
447 			else j=9;
448 			if ((t|32)=='f')
449 				p = MIN(p,MAX(0,9*(z-r-1)-j));
450 			else
451 				p = MIN(p,MAX(0,9*(z-r-1)+e-j));
452 		}
453 	}
454 	if (p > INT_MAX-1-(p || (fl&ALT_FORM)))
455 		return -1;
456 	l = 1 + p + (p || (fl&ALT_FORM));
457 	if ((t|32)=='f') {
458 		if (e > INT_MAX-l) return -1;
459 		if (e>0) l+=e;
460 	} else {
461 		estr=fmt_u(e<0 ? -e : e, ebuf);
462 		while(ebuf-estr<2) *--estr='0';
463 		*--estr = (e<0 ? '-' : '+');
464 		*--estr = t;
465 		if (ebuf-estr > INT_MAX-l) return -1;
466 		l += ebuf-estr;
467 	}
468 
469 	if (l > INT_MAX-pl) return -1;
470 	pad(f, ' ', w, pl+l, fl);
471 	out(f, prefix, pl);
472 	pad(f, '0', w, pl+l, fl^ZERO_PAD);
473 
474 	if ((t|32)=='f') {
475 		if (a>r) a=r;
476 		for (d=a; d<=r; d++) {
477 			char *s = fmt_u(*d, buf+9);
478 			if (d!=a) while (s>buf) *--s='0';
479 			else if (s==buf+9) *--s='0';
480 			out(f, s, buf+9-s);
481 		}
482 		if (p || (fl&ALT_FORM)) out(f, ".", 1);
483 		for (; d<z && p>0; d++, p-=9) {
484 			char *s = fmt_u(*d, buf+9);
485 			while (s>buf) *--s='0';
486 			out(f, s, MIN(9,p));
487 		}
488 		pad(f, '0', p+9, 9, 0);
489 	} else {
490 		if (z<=a) z=a+1;
491 		for (d=a; d<z && p>=0; d++) {
492 			char *s = fmt_u(*d, buf+9);
493 			if (s==buf+9) *--s='0';
494 			if (d!=a) while (s>buf) *--s='0';
495 			else {
496 				out(f, s++, 1);
497 				if (p>0||(fl&ALT_FORM)) out(f, ".", 1);
498 			}
499 			out(f, s, MIN(buf+9-s, p));
500 			p -= buf+9-s;
501 		}
502 		pad(f, '0', p+18, 18, 0);
503 		out(f, estr, ebuf-estr);
504 	}
505 
506 	pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
507 
508 	return MAX(w, pl+l);
509 }
510 #endif
511 
getint(char ** s)512 static int getint(char **s) {
513 	int i;
514 	for (i=0; isdigit(**s); (*s)++) {
515 		if (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;
516 		else i = 10*i + (**s-'0');
517 	}
518 	return i;
519 }
520 
should_filter_number(uintmax_t number,char ** format_string,int filter_number,int use_filter_modifiers)521 static int should_filter_number(uintmax_t number, char **format_string, int filter_number, int use_filter_modifiers)
522 {
523 	char currChar;
524 
525 	/* We only filter numbers on a certain range
526 	 * (a number outside of +/-4096 will be filtered).*/
527 	filter_number = filter_number && NUMBER_IN_FILTER_RANGE(number);
528 
529 	/* We will check if we have an override filtering modifier.*/
530 	currChar = **format_string;
531 
532 	/* This is a not filtered call, we should not "eat" the extra x.*/
533 	if (!use_filter_modifiers) {
534 		return filter_number;
535 	}
536 
537 	if (currChar == 0) {
538 		/* We were already at the end of the string.*/
539 		return filter_number;
540 	}
541 	switch (currChar)
542 	{
543 		case 'x':
544 			/* We really want to print this character.*/
545 			filter_number = 0;
546 			/* We are consuming this character, advance format string.*/
547 			(*format_string)++;
548 			break;
549 		default:
550 			/* We didn't understood the next character,
551 			 * normal parsing code will take care of it.*/
552 			break;
553 	}
554 	return filter_number;
555 }
556 
printf_core(FILE * f,const char * fmt,va_list * ap,union arg * nl_arg,int * nl_type,int filtered_on_release)557 static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type, int filtered_on_release)
558 {
559 	char *a, *z, *s=(char *)fmt;
560 	unsigned l10n=0, fl;
561 	int w, p, xp;
562 	union arg arg;
563 	int argpos;
564 	unsigned st, ps;
565 	int cnt=0, l=0;
566 	size_t i;
567 	char buf[sizeof(uintmax_t)*3+3+STDIO_MANT_DIG/4];
568 	const char *prefix;
569 	int t, pl;
570 #if STDIO_NO_FORMAT_WIDE != 1
571 	wchar_t wc[2], *ws;
572 	char mb[4];
573 #endif
574 	int use_filter_modifiers;
575 
576 	/* Keeping track if new filtering modifier (x) should be printed or not.*/
577 	use_filter_modifiers = filtered_on_release;
578 
579 #if RELEASE_BUILD == 0
580 	/* We are not on a release build, do not filter.*/
581 	filtered_on_release = 0;
582 #endif
583 	for (;;) {
584 		/* This error is only specified for snprintf, but since it's
585 		 * unspecified for other forms, do the same. Stop immediately
586 		 * on overflow; otherwise %n could produce wrong results. */
587 		if (l > INT_MAX - cnt) goto overflow;
588 
589 		/* Update output count, end loop when fmt is exhausted */
590 		cnt += l;
591 		if (!*s) break;
592 
593 		/* Handle literal text and %% format specifiers */
594 		for (a=s; *s && *s!='%'; s++);
595 		for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);
596 		if (z-a > INT_MAX-cnt) goto overflow;
597 		l = z-a;
598 		if (f) out(f, a, l);
599 		if (l) continue;
600 
601 		/* $ is a non C standard specifier to
602 		 * refer to an argument by position.*/
603 		if (isdigit(s[1]) && s[2]=='$') {
604 			l10n=1;
605 			argpos = s[1]-'0';
606 			s+=3;
607 		} else {
608 			argpos = -1;
609 			s++;
610 		}
611 
612 		/* Read modifier flags */
613 		/* Code takes advantages that all flags fit on 32 bit to
614 		 * represent each flag as a bit on a word, it will iterate
615 		 * over the input until it cannot find another flag.*/
616 		for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
617 			fl |= 1U<<*s-' ';
618 
619 		/* Read field width */
620 		if (*s=='*') {
621 			if (isdigit(s[1]) && s[2]=='$') {
622 				l10n=1;
623 				nl_type[s[1]-'0'] = INT;
624 				w = nl_arg[s[1]-'0'].i;
625 				s+=3;
626 			} else if (!l10n) {
627 				w = f ? va_arg(*ap, int) : 0;
628 				s++;
629 			} else goto inval;
630 			if (w<0) fl|=LEFT_ADJ, w=-w;
631 		} else if ((w=getint(&s))<0) goto overflow;
632 
633 		/* Read precision */
634 		if (*s=='.' && s[1]=='*') {
635 			if (isdigit(s[2]) && s[3]=='$') {
636 				nl_type[s[2]-'0'] = INT;
637 				p = nl_arg[s[2]-'0'].i;
638 				s+=4;
639 			} else if (!l10n) {
640 				p = f ? va_arg(*ap, int) : 0;
641 				s+=2;
642 			} else goto inval;
643 			xp = (p>=0);
644 		} else if (*s=='.') {
645 			s++;
646 			p = getint(&s);
647 			xp = 1;
648 		} else {
649 			p = -1;
650 			xp = 0;
651 		}
652 
653 		/* Format specifier state machine */
654 		/* Code uses a state machine to figure out how big a
655 		 * specific argument is depending on its specifiers;
656 		 * for example it is used to give different sizes if
657 		 * an argument is tagged as lu (ULONG) vs u (UINT).
658 		 * st = current state.
659 		 * ps = previous state. Mainly used to figure out
660 		 *      the size of a pointer for n*/
661 		st=0;
662 		do {
663 			if (OOB(*s)) goto inval;
664 			ps=st;
665 			st=states[st]S(*s++);
666 		} while (st-1<STOP);
667 		if (!st) goto inval;
668 
669 		/* Check validity of argument type (nl/normal) */
670 		if (st==NOARG) {
671 			if (argpos>=0) goto inval;
672 		} else {
673 			if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
674 			else if (f) pop_arg(&arg, st, ap);
675 			else return 0;
676 		}
677 
678 		if (!f) continue;
679 
680 		z = buf + sizeof(buf);
681 		prefix = "-+   0X0x";
682 		pl = 0;
683 		t = s[-1];
684 
685 		/* Transform ls,lc -> S,C */
686 		if (ps && (t&15)==3) t&=~32;
687 
688 		/* - and 0 flags are mutually exclusive */
689 		if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;
690 
691 		switch(t) {
692 		case 'n':
693 			switch(ps) {
694 			case BARE: *(int *)arg.p = cnt; break;
695 			case LPRE: *(long *)arg.p = cnt; break;
696 			case LLPRE: *(long long *)arg.p = cnt; break;
697 			case HPRE: *(unsigned short *)arg.p = cnt; break;
698 			case HHPRE: *(unsigned char *)arg.p = cnt; break;
699 			case ZTPRE: *(size_t *)arg.p = cnt; break;
700 			case JPRE: *(uintmax_t *)arg.p = cnt; break;
701 			}
702 			continue;
703 		case 'p':
704 			p = MAX(p, 2*sizeof(void*));
705 			t = 'x';
706 			fl |= ALT_FORM;
707 		case 'x': case 'X':
708 			/*z is a reverse pointer to the char buffer 'buf'*/
709 			if (should_filter_number(arg.i, &s, filtered_on_release, use_filter_modifiers)) {
710 				a = fmt_filter(arg.i, z);
711 			} else {
712 				a = fmt_x(arg.i, z, t&32);
713 			}
714 			if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2;
715 			if (0) {
716 		case 'o':
717 			if (should_filter_number(arg.i, &s, filtered_on_release, use_filter_modifiers)) {
718 				a = fmt_filter(arg.i, z);
719 			} else {
720 				a = fmt_o(arg.i, z);
721 			}
722 			if ((fl&ALT_FORM) && p<z-a+1) p=z-a+1;
723 			} if (0) {
724 		case 'd': case 'i':
725 			pl=1;
726 			if (arg.i>INTMAX_MAX) {
727 				arg.i=-arg.i;
728 			} else if (fl & MARK_POS) {
729 				prefix++;
730 			} else if (fl & PAD_POS) {
731 				prefix+=2;
732 			} else pl=0;
733 		case 'u':
734 			if (should_filter_number(arg.i, &s, filtered_on_release, use_filter_modifiers)) {
735 				/* Removing any (i.e. negative) prefix on filtered
736 			 	 * int prints pl is the length of the prefix to be
737 				 * printed.*/
738 				pl = 0;
739 				a = fmt_filter(arg.i, z);
740 			} else {
741 				a = fmt_u(arg.i, z);
742 			}
743 			}
744 			/*xp and p are set by the set precision code.
745 			 * xp: use precision
746 			 * p: precision*/
747 			if (xp && p<0) goto overflow;
748 			if (xp) fl &= ~ZERO_PAD;
749 			if (!arg.i && !p) {
750 				a=z;
751 				break;
752 			}
753 			p = MAX(p, z-a + !arg.i);
754 			break;
755 		case 'c':
756 			*(a=z-(p=1))=arg.i;
757 			fl &= ~ZERO_PAD;
758 			break;
759 		case 'm':
760 #if STDIO_NO_FORMAT_M == 1
761 			if (1) a = "(disabled)"; else
762 #else
763 			if (1) a = strerror(errno); else
764 #endif
765 		case 's':
766 			a = arg.p ? arg.p : "(null)";
767 			z = a + strnlen(a, p<0 ? INT_MAX : p);
768 			if (p<0 && *z) goto overflow;
769 			p = z-a;
770 			fl &= ~ZERO_PAD;
771 			break;
772 #if STDIO_NO_FORMAT_WIDE == 1
773 		case 'C':
774 		case 'S':
775 			a = "(disabled)";
776 			z = a + strnlen(a, p<0 ? INT_MAX : p);
777 			if (p<0 && *z) goto overflow;
778 			p = z-a;
779 			fl &= ~ZERO_PAD;
780 			break;
781 #else
782 		case 'C':
783 			wc[0] = arg.i;
784 			wc[1] = 0;
785 			arg.p = wc;
786 			p = -1;
787 		case 'S':
788 			ws = arg.p;
789 			for (i=l=0; i<p && *ws && (l=wctomb(mb, *ws++))>=0 && l<=p-i; i+=l);
790 			if (l<0) return -1;
791 			if (i > INT_MAX) goto overflow;
792 			p = i;
793 			pad(f, ' ', w, p, fl);
794 			ws = arg.p;
795 			for (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l)
796 				out(f, mb, l);
797 			pad(f, ' ', w, p, fl^LEFT_ADJ);
798 			l = w>p ? w : p;
799 			continue;
800 #endif
801 		case 'e': case 'f': case 'g': case 'a':
802 		case 'E': case 'F': case 'G': case 'A':
803 #if STDIO_FLOAT == 0
804 			a = "(disabled)";
805 			z = a + strnlen(a, p<0 ? INT_MAX : p);
806 			if (p<0 && *z) goto overflow;
807 			p = z-a;
808 			fl &= ~ZERO_PAD;
809 			break;
810 #else
811 			if (xp && p<0) goto overflow;
812 #if !WITH_NO_FP
813 			l = fmt_fp(f, arg.f, w, p, fl, t);
814 #else
815 			fputs("Floating point code is not supported\n", stderr);
816 			abort();
817 #endif
818 			if (l<0) goto overflow;
819 			continue;
820 #endif
821 		}
822 
823 		if (p < z-a) p = z-a;
824 		if (p > INT_MAX-pl) goto overflow;
825 		if (w < pl+p) w = pl+p;
826 		if (w > INT_MAX-cnt) goto overflow;
827 
828 		pad(f, ' ', w, pl+p, fl);
829 		out(f, prefix, pl);
830 		pad(f, '0', w, pl+p, fl^ZERO_PAD);
831 		pad(f, '0', p, z-a, 0);
832 		out(f, a, z-a);
833 		pad(f, ' ', w, pl+p, fl^LEFT_ADJ);
834 
835 		l = w;
836 	}
837 
838 	if (f) return cnt;
839 	if (!l10n) return 0;
840 
841 	for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
842 		pop_arg(nl_arg+i, nl_type[i], ap);
843 	for (; i<=NL_ARGMAX && !nl_type[i]; i++);
844 	if (i<=NL_ARGMAX) goto inval;
845 	return 1;
846 
847 inval:
848 	errno = EINVAL;
849 	return -1;
850 overflow:
851 	errno = EOVERFLOW;
852 	return -1;
853 }
854 
vfprintf_worker(FILE * restrict f,const char * restrict fmt,va_list ap,int filtered_on_release)855 int vfprintf_worker(FILE *restrict f, const char *restrict fmt, va_list ap, int filtered_on_release)
856 {
857 	va_list ap2;
858 	int nl_type[NL_ARGMAX+1] = {0};
859 	union arg nl_arg[NL_ARGMAX+1];
860 	unsigned char internal_buf[80], *saved_buf = 0;
861 	int olderr;
862 	int ret;
863 
864 	/* the copy allows passing va_list* even if va_list is an array */
865 	va_copy(ap2, ap);
866 	if (printf_core(0, fmt, &ap2, nl_arg, nl_type, filtered_on_release) < 0) {
867 		va_end(ap2);
868 		return -1;
869 	}
870 
871 	FLOCK(f);
872 	olderr = f->flags & F_ERR;
873 	if (f->mode < 1) f->flags &= ~F_ERR;
874 	if (!f->buf_size) {
875 		saved_buf = f->buf;
876 		f->buf = internal_buf;
877 		f->buf_size = sizeof internal_buf;
878 		f->wpos = f->wbase = f->wend = 0;
879 	}
880 	if (!f->wend && __towrite(f)) ret = -1;
881 	else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type, filtered_on_release);
882 	if (saved_buf) {
883 		f->write(f, 0, 0);
884 		if (!f->wpos) ret = -1;
885 		f->buf = saved_buf;
886 		f->buf_size = 0;
887 		f->wpos = f->wbase = f->wend = 0;
888 	}
889 	if (f->flags & F_ERR) ret = -1;
890 	f->flags |= olderr;
891 	FUNLOCK(f);
892 	va_end(ap2);
893 	return ret;
894 }
895