mirror of
https://github.com/openharmony/third_party_rust_encoding_rs.git
synced 2026-07-21 02:05:23 -04:00
Give InputEmpty correct precedent when encoding with replacement.
This commit is contained in:
@@ -96,6 +96,12 @@ encoding_rs is
|
||||
|
||||
## Release Notes
|
||||
|
||||
### 0.6.7
|
||||
|
||||
* Give `InputEmpty` correct precedence over `OutputFull` when encoding
|
||||
with replacement and the output buffer passed in is too short or the
|
||||
remaining space in the output buffer is too small after a replacement.
|
||||
|
||||
### 0.6.6
|
||||
|
||||
* Correct max length calculation when a partial BOM prefix is part of
|
||||
|
||||
@@ -1468,6 +1468,14 @@ for variant in encoder_variants:
|
||||
variant_file.write('''}
|
||||
|
||||
impl VariantEncoder {
|
||||
pub fn has_pending_state(&self) -> bool {
|
||||
match *self {
|
||||
VariantEncoder::Iso2022Jp(ref v) => {
|
||||
v.has_pending_state()
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
''')
|
||||
|
||||
write_variant_method("max_buffer_length_from_utf16_without_replacement", False, [("u16_length", "usize")], "Option<usize>", encoder_variants, [], "Encoder")
|
||||
|
||||
@@ -402,6 +402,14 @@ impl Iso2022JpEncoder {
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn has_pending_state(&self) -> bool {
|
||||
match self.state {
|
||||
Iso2022JpEncoderState::Ascii => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn max_buffer_length_from_utf16_without_replacement(&self,
|
||||
u16_length: usize)
|
||||
-> Option<usize> {
|
||||
|
||||
+152
@@ -3523,6 +3523,15 @@ impl Encoder {
|
||||
self.encoding
|
||||
}
|
||||
|
||||
/// Returns `true` if this is an ISO-2022-JP encoder that's not in the
|
||||
/// ASCII state and `false` otherwise.
|
||||
///
|
||||
/// XXX make this public to allow other libs to implement custom replacement
|
||||
/// strategies and still get the `InputEmpty` semantics right.
|
||||
fn has_pending_state(&self) -> bool {
|
||||
self.variant.has_pending_state()
|
||||
}
|
||||
|
||||
/// Query the worst-case output size when encoding from UTF-8 with
|
||||
/// replacement.
|
||||
///
|
||||
@@ -3574,6 +3583,9 @@ impl Encoder {
|
||||
dst_len
|
||||
} else {
|
||||
if dst_len < NCR_EXTRA {
|
||||
if src.is_empty() && !(last && self.has_pending_state()) {
|
||||
return (CoderResult::InputEmpty, 0, 0, false);
|
||||
}
|
||||
return (CoderResult::OutputFull, 0, 0, false);
|
||||
}
|
||||
dst_len - NCR_EXTRA
|
||||
@@ -3603,6 +3615,12 @@ impl Encoder {
|
||||
// transitioning to ASCII when returning with Unmappable.
|
||||
total_written += write_ncr(unmappable, &mut dst[total_written..]);
|
||||
if total_written >= effective_dst_len {
|
||||
if total_read == src.len() && !(last && self.has_pending_state()) {
|
||||
return (CoderResult::InputEmpty,
|
||||
total_read,
|
||||
total_written,
|
||||
had_unmappables);
|
||||
}
|
||||
return (CoderResult::OutputFull,
|
||||
total_read,
|
||||
total_written,
|
||||
@@ -3724,6 +3742,9 @@ impl Encoder {
|
||||
dst_len
|
||||
} else {
|
||||
if dst_len < NCR_EXTRA {
|
||||
if src.is_empty() && !(last && self.has_pending_state()) {
|
||||
return (CoderResult::InputEmpty, 0, 0, false);
|
||||
}
|
||||
return (CoderResult::OutputFull, 0, 0, false);
|
||||
}
|
||||
dst_len - NCR_EXTRA
|
||||
@@ -3759,6 +3780,12 @@ impl Encoder {
|
||||
// printable ASCII excluding \ and ~.
|
||||
total_written += write_ncr(unmappable, &mut dst[total_written..]);
|
||||
if total_written >= effective_dst_len {
|
||||
if total_read == src.len() && !(last && self.has_pending_state()) {
|
||||
return (CoderResult::InputEmpty,
|
||||
total_read,
|
||||
total_written,
|
||||
had_unmappables);
|
||||
}
|
||||
return (CoderResult::OutputFull,
|
||||
total_read,
|
||||
total_written,
|
||||
@@ -4504,4 +4531,129 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_short_buffer_with_iso_2022_jp_ascii_from_utf8() {
|
||||
let mut dst = [0u8; 8];
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf8("", &mut dst[..], false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf8("", &mut dst[..], true);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_short_buffer_with_iso_2022_jp_roman_from_utf8() {
|
||||
let mut dst = [0u8; 15];
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf8("\u{A5}", &mut dst[..], false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf8("", &mut dst[..8], false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf8("", &mut dst[..8], true);
|
||||
assert_eq!(result, CoderResult::OutputFull);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buffer_end_iso_2022_jp_from_utf8() {
|
||||
let mut dst = [0u8; 17];
|
||||
{
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
let (result, _, _, _) = encoder.encode_from_utf8("\u{A5}\u{1F4A9}",
|
||||
&mut dst[..],
|
||||
false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
let (result, _, _, _) = encoder.encode_from_utf8("\u{A5}\u{1F4A9}", &mut dst[..], true);
|
||||
assert_eq!(result, CoderResult::OutputFull);
|
||||
}
|
||||
{
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
let (result, _, _, _) = encoder.encode_from_utf8("\u{1F4A9}", &mut dst[..12], false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
let (result, _, _, _) = encoder.encode_from_utf8("\u{1F4A9}", &mut dst[..12], true);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_too_short_buffer_with_iso_2022_jp_ascii_from_utf16() {
|
||||
let mut dst = [0u8; 8];
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf16(&[0u16; 0], &mut dst[..], false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf16(&[0u16; 0], &mut dst[..], true);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_short_buffer_with_iso_2022_jp_roman_from_utf16() {
|
||||
let mut dst = [0u8; 15];
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf16(&[0xA5u16], &mut dst[..], false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf16(&[0u16; 0], &mut dst[..8], false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let (result, _, _, _) = encoder.encode_from_utf16(&[0u16; 0], &mut dst[..8], true);
|
||||
assert_eq!(result, CoderResult::OutputFull);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buffer_end_iso_2022_jp_from_utf16() {
|
||||
let mut dst = [0u8; 17];
|
||||
{
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
let (result, _, _, _) = encoder.encode_from_utf16(&[0xA5u16, 0xD83Du16, 0xDCA9u16],
|
||||
&mut dst[..],
|
||||
false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
let (result, _, _, _) = encoder.encode_from_utf16(&[0xA5u16, 0xD83Du16, 0xDCA9u16],
|
||||
&mut dst[..],
|
||||
true);
|
||||
assert_eq!(result, CoderResult::OutputFull);
|
||||
}
|
||||
{
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
let (result, _, _, _) = encoder.encode_from_utf16(&[0xD83Du16, 0xDCA9u16],
|
||||
&mut dst[..12],
|
||||
false);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
{
|
||||
let mut encoder = ISO_2022_JP.new_encoder();
|
||||
let (result, _, _, _) = encoder.encode_from_utf16(&[0xD83Du16, 0xDCA9u16],
|
||||
&mut dst[..12],
|
||||
true);
|
||||
assert_eq!(result, CoderResult::InputEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -171,6 +171,12 @@ pub enum VariantEncoder {
|
||||
}
|
||||
|
||||
impl VariantEncoder {
|
||||
pub fn has_pending_state(&self) -> bool {
|
||||
match *self {
|
||||
VariantEncoder::Iso2022Jp(ref v) => v.has_pending_state(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn max_buffer_length_from_utf16_without_replacement(&self,
|
||||
u16_length: usize)
|
||||
-> Option<usize> {
|
||||
|
||||
Reference in New Issue
Block a user