mirror of
https://git.musl-libc.org/git/musl
synced 2025-01-06 23:02:10 +03:00
prevent invalid reads of nl_arg in printf_core
printf_core() runs twice, and during its first run, nl_arg is uninitialized and must not be read. It gets initialized at the end of the first run. Conversely, nl_type does not need to be set during the second run, as its useful life has ended at that point, since the only time it is read is during that exact same initialization. Therefore we can simply alternate the assignments. p and w do still need to get values assigned to them, since at least one line in the same if-statement depends on that, but they can be dummy values. arg does not need to be assigned, since in the first run, we encounter a continue statement before using the argument.
This commit is contained in:
parent
c5f4b2dfea
commit
7d358599d4
@ -478,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;
|
||||
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;
|
||||
@ -491,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]=='$') {
|
||||
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;
|
||||
@ -521,8 +521,10 @@ 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 (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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user