@@ -41,7 +41,7 @@ impl<'a> Attribute<'a> {
4141 ///
4242 /// This method is available only if `encoding` feature is **not** enabled.
4343 #[ cfg( any( doc, not( feature = "encoding" ) ) ) ]
44- pub fn unescape_value ( & self ) -> XmlResult < Cow < str > > {
44+ pub fn unescape_value ( & self ) -> XmlResult < Cow < ' a , str > > {
4545 self . unescape_value_with ( |_| None )
4646 }
4747
@@ -61,19 +61,26 @@ impl<'a> Attribute<'a> {
6161 pub fn unescape_value_with < ' entity > (
6262 & self ,
6363 resolve_entity : impl Fn ( & str ) -> Option < & ' entity str > ,
64- ) -> XmlResult < Cow < str > > {
64+ ) -> XmlResult < Cow < ' a , str > > {
6565 // from_utf8 should never fail because content is always UTF-8 encoded
66- Ok ( unescape_with (
67- std:: str:: from_utf8 ( & self . value ) ?,
68- resolve_entity,
69- ) ?)
66+ let decoded = match & self . value {
67+ Cow :: Borrowed ( bytes) => Cow :: Borrowed ( std:: str:: from_utf8 ( bytes) ?) ,
68+ // Convert to owned, because otherwise Cow will be bound with wrong lifetime
69+ Cow :: Owned ( bytes) => Cow :: Owned ( std:: str:: from_utf8 ( bytes) ?. to_string ( ) ) ,
70+ } ;
71+
72+ match unescape_with ( & decoded, resolve_entity) ? {
73+ // Because result is borrowed, no replacements was done and we can use original string
74+ Cow :: Borrowed ( _) => Ok ( decoded) ,
75+ Cow :: Owned ( s) => Ok ( s. into ( ) ) ,
76+ }
7077 }
7178
7279 /// Decodes then unescapes the value.
7380 ///
7481 /// This will allocate if the value contains any escape sequences or in
7582 /// non-UTF-8 encoding.
76- pub fn decode_and_unescape_value < B > ( & self , reader : & Reader < B > ) -> XmlResult < Cow < str > > {
83+ pub fn decode_and_unescape_value < B > ( & self , reader : & Reader < B > ) -> XmlResult < Cow < ' a , str > > {
7784 self . decode_and_unescape_value_with ( reader, |_| None )
7885 }
7986
@@ -85,8 +92,12 @@ impl<'a> Attribute<'a> {
8592 & self ,
8693 reader : & Reader < B > ,
8794 resolve_entity : impl Fn ( & str ) -> Option < & ' entity str > ,
88- ) -> XmlResult < Cow < str > > {
89- let decoded = reader. decoder ( ) . decode ( & * self . value ) ?;
95+ ) -> XmlResult < Cow < ' a , str > > {
96+ let decoded = match & self . value {
97+ Cow :: Borrowed ( bytes) => reader. decoder ( ) . decode ( bytes) ?,
98+ // Convert to owned, because otherwise Cow will be bound with wrong lifetime
99+ Cow :: Owned ( bytes) => reader. decoder ( ) . decode ( bytes) ?. into_owned ( ) . into ( ) ,
100+ } ;
90101
91102 match unescape_with ( & decoded, resolve_entity) ? {
92103 // Because result is borrowed, no replacements was done and we can use original string
0 commit comments