When not fuzzing, make the lossy conversions to Latin1 debug_assert! if

the argument is not in the Latin1 range.

In principle, this is a semver breaking change, but only when debug assertions
are enabled and only when the caller violates the intended use of the
function, so not treating this as semver breaking.
This commit is contained in:
Henri Sivonen
2018-08-08 14:26:25 +03:00
parent b3e9adaa95
commit 80da7a3fc4
2 changed files with 35 additions and 1 deletions
+6
View File
@@ -244,6 +244,12 @@ used in Firefox.
## Release Notes
### 0.8.5
* If debug assertions are enabled but fuzzing isn't enabled, lossy conversions
to Latin1 in the `mem` module assert that the input is in the range
U+0000...U+00FF (inclusive).
### 0.8.4
* Fix SSE2-specific, `simd-accel`-specific memory corruption introduced in
+29 -1
View File
@@ -31,6 +31,10 @@ use super::EncoderResult;
use ascii::*;
use utf_8::*;
macro_rules! non_fuzz_debug_assert {
($($arg:tt)*) => (if !cfg!(fuzzing) { debug_assert!($($arg)*); })
}
cfg_if!{
if #[cfg(feature = "simd-accel")] {
use ::std::intrinsics::unlikely;
@@ -1718,6 +1722,7 @@ pub fn convert_latin1_to_str(src: &[u8], dst: &mut str) -> usize {
/// each output byte.
///
/// If the input does not fulfill the condition stated above, this function
/// panics if debug assertions are enabled (and fuzzing isn't) and otherwise
/// does something that is memory-safe without any promises about any
/// properties of the output. In particular, callers shouldn't assume the
/// output to be the same across crate versions or CPU architectures and
@@ -1731,12 +1736,16 @@ pub fn convert_latin1_to_str(src: &[u8], dst: &mut str) -> usize {
/// # Panics
///
/// Panics if the destination buffer is shorter than stated above.
///
/// If debug assertions are enabled (and not fuzzing) and the input is
/// not in the range U+0000 to U+00FF, inclusive.
#[inline]
pub fn convert_utf8_to_latin1_lossy(src: &[u8], dst: &mut [u8]) -> usize {
assert!(
dst.len() >= src.len(),
"Destination must not be shorter than the source."
);
non_fuzz_debug_assert!(is_utf8_latin1(src));
let src_len = src.len();
let src_ptr = src.as_ptr();
let dst_ptr = dst.as_mut_ptr();
@@ -1777,10 +1786,11 @@ pub fn convert_utf8_to_latin1_lossy(src: &[u8], dst: &mut [u8]) -> usize {
/// each output byte.
///
/// If the input does not fulfill the condition stated above, this function
/// panics if debug assertions are enabled (and fuzzing isn't) and otherwise
/// does something that is memory-safe without any promises about any
/// properties of the output. In particular, callers shouldn't assume the
/// output to be the same across crate versions or CPU architectures and
/// should not assume that non-Basic Latin input can't map to ASCII output.
/// should not assume that non-ASCII input can't map to ASCII output.
///
/// The length of the destination buffer must be at least the length of the
/// source buffer.
@@ -1790,12 +1800,16 @@ pub fn convert_utf8_to_latin1_lossy(src: &[u8], dst: &mut [u8]) -> usize {
/// # Panics
///
/// Panics if the destination buffer is shorter than stated above.
///
/// If debug assertions are enabled (and not fuzzing) and the input is
/// not in the range U+0000 to U+00FF, inclusive.
#[inline]
pub fn convert_utf16_to_latin1_lossy(src: &[u16], dst: &mut [u8]) {
assert!(
dst.len() >= src.len(),
"Destination must not be shorter than the source."
);
non_fuzz_debug_assert!(is_utf16_latin1(src));
unsafe {
pack_latin1(src.as_ptr(), dst.as_mut_ptr(), src.len());
}
@@ -2163,6 +2177,13 @@ mod tests {
assert_eq!(dst, reference);
}
#[test]
#[should_panic]
fn test_convert_utf8_to_latin1_lossy_panics() {
let mut dst = [0u8; 16];
let _ = convert_utf8_to_latin1_lossy("\u{100}".as_bytes(), &mut dst[..]);
}
#[test]
fn test_convert_utf16_to_latin1_lossy() {
let mut src: Vec<u16> = Vec::with_capacity(256);
@@ -2179,6 +2200,13 @@ mod tests {
assert_eq!(dst, reference);
}
#[test]
#[should_panic]
fn test_convert_utf16_to_latin1_lossy_panics() {
let mut dst = [0u8; 16];
let _ = convert_utf16_to_latin1_lossy(&[0x0100u16], &mut dst[..]);
}
#[test]
fn test_utf16_valid_up_to() {
let valid = vec![