@@ -1415,7 +1415,11 @@ impl<'a> Formatter<'a> {
1415
1415
/// Takes the formatted parts and applies the padding.
1416
1416
/// Assumes that the caller already has rendered the parts with required precision,
1417
1417
/// so that `self.precision` can be ignored.
1418
- fn pad_formatted_parts ( & mut self , formatted : & numfmt:: Formatted < ' _ > ) -> Result {
1418
+ ///
1419
+ /// # Safety
1420
+ ///
1421
+ /// Any `numfmt::Part::Copy` parts in `formatted` must contain valid UTF-8.
1422
+ unsafe fn pad_formatted_parts ( & mut self , formatted : & numfmt:: Formatted < ' _ > ) -> Result {
1419
1423
if let Some ( mut width) = self . width {
1420
1424
// for the sign-aware zero padding, we render the sign first and
1421
1425
// behave as if we had no sign from the beginning.
@@ -1438,31 +1442,35 @@ impl<'a> Formatter<'a> {
1438
1442
let len = formatted. len ( ) ;
1439
1443
let ret = if width <= len {
1440
1444
// no padding
1441
- self . write_formatted_parts ( & formatted)
1445
+ // SAFETY: Per the precondition.
1446
+ unsafe { self . write_formatted_parts ( & formatted) }
1442
1447
} else {
1443
1448
let post_padding = self . padding ( width - len, Alignment :: Right ) ?;
1444
- self . write_formatted_parts ( & formatted) ?;
1449
+ // SAFETY: Per the precondition.
1450
+ unsafe {
1451
+ self . write_formatted_parts ( & formatted) ?;
1452
+ }
1445
1453
post_padding. write ( self )
1446
1454
} ;
1447
1455
self . fill = old_fill;
1448
1456
self . align = old_align;
1449
1457
ret
1450
1458
} else {
1451
1459
// this is the common case and we take a shortcut
1452
- self . write_formatted_parts ( formatted)
1460
+ // SAFETY: Per the precondition.
1461
+ unsafe { self . write_formatted_parts ( formatted) }
1453
1462
}
1454
1463
}
1455
1464
1456
- fn write_formatted_parts ( & mut self , formatted : & numfmt:: Formatted < ' _ > ) -> Result {
1457
- fn write_bytes ( buf : & mut dyn Write , s : & [ u8 ] ) -> Result {
1465
+ /// # Safety
1466
+ ///
1467
+ /// Any `numfmt::Part::Copy` parts in `formatted` must contain valid UTF-8.
1468
+ unsafe fn write_formatted_parts ( & mut self , formatted : & numfmt:: Formatted < ' _ > ) -> Result {
1469
+ unsafe fn write_bytes ( buf : & mut dyn Write , s : & [ u8 ] ) -> Result {
1458
1470
// SAFETY: This is used for `numfmt::Part::Num` and `numfmt::Part::Copy`.
1459
1471
// It's safe to use for `numfmt::Part::Num` since every char `c` is between
1460
- // `b'0'` and `b'9'`, which means `s` is valid UTF-8.
1461
- // It's also probably safe in practice to use for `numfmt::Part::Copy(buf)`
1462
- // since `buf` should be plain ASCII, but it's possible for someone to pass
1463
- // in a bad value for `buf` into `numfmt::to_shortest_str` since it is a
1464
- // public function.
1465
- // FIXME: Determine whether this could result in UB.
1472
+ // `b'0'` and `b'9'`, which means `s` is valid UTF-8. It's safe to use for
1473
+ // `numfmt::Part::Copy` due to this function's precondition.
1466
1474
buf. write_str ( unsafe { str:: from_utf8_unchecked ( s) } )
1467
1475
}
1468
1476
@@ -1489,11 +1497,15 @@ impl<'a> Formatter<'a> {
1489
1497
* c = b'0' + ( v % 10 ) as u8 ;
1490
1498
v /= 10 ;
1491
1499
}
1492
- write_bytes ( self . buf , & s[ ..len] ) ?;
1500
+ // SAFETY: Per the precondition.
1501
+ unsafe {
1502
+ write_bytes ( self . buf , & s[ ..len] ) ?;
1503
+ }
1493
1504
}
1494
- numfmt:: Part :: Copy ( buf) => {
1505
+ // SAFETY: Per the precondition.
1506
+ numfmt:: Part :: Copy ( buf) => unsafe {
1495
1507
write_bytes ( self . buf , buf) ?;
1496
- }
1508
+ } ,
1497
1509
}
1498
1510
}
1499
1511
Ok ( ( ) )
0 commit comments