Skip to content

Commit f774ede

Browse files
committed
Escape ]]> in CDATA
1 parent 276f54f commit f774ede

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Merged `ParserConfig2` back into `ParserConfig`
66
* Added option to the writer to pass through XML markup unmodified
77
* `xml-analyze` binary has been moved to examples
8+
* Writer escapes `--` in comments and `]]>` in CDATA
89

910
## Version 0.8.27
1011

src/writer/emitter.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,19 @@ impl Emitter {
400400
if self.config.cdata_to_characters {
401401
self.emit_characters(target, content)
402402
} else {
403-
// TODO: escape ']]>' characters in CDATA as two adjacent CDATA blocks
404403
target.write_all(b"<![CDATA[")?;
405-
target.write_all(content.as_bytes())?;
406-
target.write_all(b"]]>")?;
407404

405+
for chunk in content.split_inclusive("]]>") {
406+
let chunk_safe = chunk.strip_suffix("]]>");
407+
let emit_escaped = chunk_safe.is_some();
408+
409+
target.write_all(chunk_safe.unwrap_or(chunk).as_bytes())?;
410+
if emit_escaped {
411+
target.write_all(b"]]]]><![CDATA[>")?;
412+
}
413+
}
414+
415+
target.write_all(b"]]>")?;
408416
self.after_text();
409417

410418
Ok(())

tests/event_writer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ fn accidental_cdata_suffix_in_characters_is_escaped() {
286286
unwrap_all! {
287287
w.write(XmlEvent::start_element("root"));
288288
w.write(XmlEvent::characters("[[a]]>b"));
289+
w.write(XmlEvent::cdata("c]]>data"));
289290
w.write(XmlEvent::end_element())
290291
}
291292
}
@@ -296,6 +297,8 @@ fn accidental_cdata_suffix_in_characters_is_escaped() {
296297
assert!(matches!(r.next().unwrap(), XmlEvent::StartDocument { .. }));
297298
assert!(matches!(r.next().unwrap(), XmlEvent::StartElement { .. }));
298299
assert_eq!(r.next().unwrap(), XmlEvent::Characters("[[a]]>b".into()));
300+
assert_eq!(r.next().unwrap(), XmlEvent::CData("c]]".into()));
301+
assert_eq!(r.next().unwrap(), XmlEvent::CData(">data".into()));
299302
assert!(matches!(r.next().unwrap(), XmlEvent::EndElement { .. }));
300303
assert!(matches!(r.next().unwrap(), XmlEvent::EndDocument));
301304
}

0 commit comments

Comments
 (0)