projects
/
musl
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fix (normal, narrow) printf erroneously processing %n after output errors
[musl]
/
src
/
stdio
/
vfprintf.c
diff --git
a/src/stdio/vfprintf.c
b/src/stdio/vfprintf.c
index
15356f5
..
2dbdb5e
100644
(file)
--- a/
src/stdio/vfprintf.c
+++ b/
src/stdio/vfprintf.c
@@
-5,6
+5,7
@@
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
+#include <stdlib.h>
#include <wchar.h>
#include <inttypes.h>
#include <math.h>
#include <wchar.h>
#include <inttypes.h>
#include <math.h>
@@
-220,6
+221,7
@@
static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)
else re=LDBL_MANT_DIG/4-1-p;
if (re) {
else re=LDBL_MANT_DIG/4-1-p;
if (re) {
+ round *= 1<<(LDBL_MANT_DIG%4);
while (re--) round*=16;
if (*prefix=='-') {
y=-y;
while (re--) round*=16;
if (*prefix=='-') {
y=-y;
@@
-476,8
+478,8
@@
static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
if (*s=='*') {
if (isdigit(s[1]) && s[2]=='$') {
l10n=1;
if (*s=='*') {
if (isdigit(s[1]) && s[2]=='$') {
l10n=1;
-
nl_type[s[1]-'0'] = INT
;
- w = nl_arg[s[1]-'0'].i;
+
if (!f) nl_type[s[1]-'0'] = INT, w = 0
;
+
else
w = nl_arg[s[1]-'0'].i;
s+=3;
} else if (!l10n) {
w = f ? va_arg(*ap, int) : 0;
s+=3;
} else if (!l10n) {
w = f ? va_arg(*ap, int) : 0;
@@
-489,8
+491,8
@@
static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
/* Read precision */
if (*s=='.' && s[1]=='*') {
if (isdigit(s[2]) && s[3]=='$') {
/* Read precision */
if (*s=='.' && s[1]=='*') {
if (isdigit(s[2]) && s[3]=='$') {
-
nl_type[s[2]-'0'] = INT
;
- p = nl_arg[s[2]-'0'].i;
+
if (!f) nl_type[s[2]-'0'] = INT, p = 0
;
+
else
p = nl_arg[s[2]-'0'].i;
s+=4;
} else if (!l10n) {
p = f ? va_arg(*ap, int) : 0;
s+=4;
} else if (!l10n) {
p = f ? va_arg(*ap, int) : 0;
@@
-519,13
+521,18
@@
static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
if (st==NOARG) {
if (argpos>=0) goto inval;
} else {
if (st==NOARG) {
if (argpos>=0) goto inval;
} else {
- if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
- else if (f) pop_arg(&arg, st, ap);
+ if (argpos>=0) {
+ if (!f) nl_type[argpos]=st;
+ else arg=nl_arg[argpos];
+ } else if (f) pop_arg(&arg, st, ap);
else return 0;
}
if (!f) continue;
else return 0;
}
if (!f) continue;
+ /* Do not process any new directives once in error state. */
+ if (ferror(f)) return -1;
+
z = buf + sizeof(buf);
prefix = "-+ 0X0x";
pl = 0;
z = buf + sizeof(buf);
prefix = "-+ 0X0x";
pl = 0;
@@
-559,7
+566,7
@@
static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
if (0) {
case 'o':
a = fmt_o(arg.i, z);
if (0) {
case 'o':
a = fmt_o(arg.i, z);
- if ((fl&ALT_FORM) && p<z-a+1) p
refix+=5, pl=
1;
+ if ((fl&ALT_FORM) && p<z-a+1) p
=z-a+
1;
} if (0) {
case 'd': case 'i':
pl=1;
} if (0) {
case 'd': case 'i':
pl=1;
@@
-574,7
+581,7
@@
static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
a = fmt_u(arg.i, z);
}
if (xp && p<0) goto overflow;
a = fmt_u(arg.i, z);
}
if (xp && p<0) goto overflow;
- if (
p>=0
) fl &= ~ZERO_PAD;
+ if (
xp
) fl &= ~ZERO_PAD;
if (!arg.i && !p) {
a=z;
break;
if (!arg.i && !p) {
a=z;
break;
@@
-673,11
+680,12
@@
int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
if (f->mode < 1) f->flags &= ~F_ERR;
if (!f->buf_size) {
saved_buf = f->buf;
if (f->mode < 1) f->flags &= ~F_ERR;
if (!f->buf_size) {
saved_buf = f->buf;
- f->
wpos = f->wbase = f->
buf = internal_buf;
+ f->buf = internal_buf;
f->buf_size = sizeof internal_buf;
f->buf_size = sizeof internal_buf;
- f->w
end = internal_buf + sizeof internal_buf
;
+ f->w
pos = f->wbase = f->wend = 0
;
}
}
- ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
+ if (!f->wend && __towrite(f)) ret = -1;
+ else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
if (saved_buf) {
f->write(f, 0, 0);
if (!f->wpos) ret = -1;
if (saved_buf) {
f->write(f, 0, 0);
if (!f->wpos) ret = -1;