Skip to content

Commit 7558577

Browse files
committed
Fix incorrect missing of trimming all-space text events when trim_text_start = false and trim_text_end = true
This is still not complete fix, because we will generate empty Event::Text although we should not do that, but it is hard to prevent generation of such event. Moreover it would be better to remove ability of automatic trimming completely, because it is anyway does not work correctly -- events should not be trimmed at boundary of text / CDATA, or text / PI, or text / comment in some cases
1 parent 31177ec commit 7558577

File tree

3 files changed

+20
-17
lines changed

3 files changed

+20
-17
lines changed

Changelog.md

+4
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@
1414

1515
### Bug Fixes
1616

17+
- [#755]: Fix incorrect missing of trimming all-space text events when
18+
`trim_text_start = false` and `trim_text_end = true`.
19+
1720
### Misc Changes
1821

1922
- [#650]: Change the type of `Event::PI` to a new dedicated `BytesPI` type.
2023

2124
[#650]: https://github.com/tafia/quick-xml/issues/650
25+
[#755]: https://github.com/tafia/quick-xml/pull/755
2226

2327

2428
## 0.32.0 -- 2024-06-10

src/reader/mod.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,21 @@ macro_rules! read_event_impl {
244244
}
245245
ReadTextResult::UpToMarkup(bytes) => {
246246
$self.state.state = ParseState::InsideMarkup;
247-
// Return Text event with `bytes` content or Eof if bytes is empty
248-
Ok($self.state.emit_text(bytes))
247+
// FIXME: Can produce an empty event if:
248+
// - event contains only spaces
249+
// - trim_text_start = false
250+
// - trim_text_end = true
251+
Ok(Event::Text($self.state.emit_text(bytes)))
249252
}
250253
ReadTextResult::UpToEof(bytes) => {
251254
$self.state.state = ParseState::Done;
252-
// Return Text event with `bytes` content or Eof if bytes is empty
253-
Ok($self.state.emit_text(bytes))
255+
// Trim bytes from end if required
256+
let event = $self.state.emit_text(bytes);
257+
if event.is_empty() {
258+
Ok(Event::Eof)
259+
} else {
260+
Ok(Event::Text(event))
261+
}
254262
}
255263
ReadTextResult::Err(e) => Err(Error::Io(e.into())),
256264
}

src/reader/state.rs

+4-13
Original file line numberDiff line numberDiff line change
@@ -52,31 +52,22 @@ pub(super) struct ReaderState {
5252
}
5353

5454
impl ReaderState {
55-
/// Trims end whitespaces from `bytes`, if required, and returns a [`Text`]
56-
/// event or an [`Eof`] event, if text after trimming is empty.
55+
/// Trims end whitespaces from `bytes`, if required, and returns a text event.
5756
///
5857
/// # Parameters
5958
/// - `bytes`: data from the start of stream to the first `<` or from `>` to `<`
60-
///
61-
/// [`Text`]: Event::Text
62-
/// [`Eof`]: Event::Eof
63-
pub fn emit_text<'b>(&mut self, bytes: &'b [u8]) -> Event<'b> {
59+
pub fn emit_text<'b>(&mut self, bytes: &'b [u8]) -> BytesText<'b> {
6460
let mut content = bytes;
6561

6662
if self.config.trim_text_end {
6763
// Skip the ending '<'
6864
let len = bytes
6965
.iter()
7066
.rposition(|&b| !is_whitespace(b))
71-
.map_or_else(|| bytes.len(), |p| p + 1);
67+
.map_or(0, |p| p + 1);
7268
content = &bytes[..len];
7369
}
74-
75-
if content.is_empty() {
76-
Event::Eof
77-
} else {
78-
Event::Text(BytesText::wrap(content, self.decoder()))
79-
}
70+
BytesText::wrap(content, self.decoder())
8071
}
8172

8273
/// reads `BytesElement` starting with a `!`,

0 commit comments

Comments
 (0)