lib: cbprintf: avoid referencing distinct union fields in a statement
An assignment from one multi-word union field to another was not safe from corruption. Copy the value out to a local value before storing it to the preferred union field. Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
0129dd6f28
commit
10180af38d
1 changed files with 9 additions and 3 deletions
|
@ -1323,6 +1323,7 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
|
||||||
{
|
{
|
||||||
char buf[CONVERTED_BUFLEN];
|
char buf[CONVERTED_BUFLEN];
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
sint_value_type sint;
|
||||||
|
|
||||||
/* Output character, returning EOF if output failed, otherwise
|
/* Output character, returning EOF if output failed, otherwise
|
||||||
* updating count.
|
* updating count.
|
||||||
|
@ -1579,11 +1580,16 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
|
||||||
sign = ' ';
|
sign = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value->sint < 0) {
|
/* sint/uint overlay in the union, and so
|
||||||
|
* can't appear in read and write operations
|
||||||
|
* in the same statement.
|
||||||
|
*/
|
||||||
|
sint = value->sint;
|
||||||
|
if (sint < 0) {
|
||||||
sign = '-';
|
sign = '-';
|
||||||
value->uint = (uint_value_type)-value->sint;
|
value->uint = (uint_value_type)-sint;
|
||||||
} else {
|
} else {
|
||||||
value->uint = (uint_value_type)value->sint;
|
value->uint = (uint_value_type)sint;
|
||||||
}
|
}
|
||||||
|
|
||||||
__fallthrough;
|
__fallthrough;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue