13
13
//! This module contains `Writer`s for escaping/unescaping HTML.
14
14
15
15
use std:: io:: { Writer , IoResult } ;
16
- use std:: { char, str } ;
16
+ use std:: char;
17
17
use entity:: ENTITIES ;
18
18
19
19
/// A `Writer` adaptor that escapes any HTML characters written to it.
@@ -32,9 +32,7 @@ pub enum EscapeMode {
32
32
/// Escapes characters for double-quoted attribute values. Escapes `&"`.
33
33
EscapeAttr ,
34
34
/// Escapes characters for single-quoted attribute values. Escapes `&'`.
35
- EscapeSingleQuoteAttr ,
36
- /// Escapes all non-printable or non-ASCII characters, with the exception of U+0000.
37
- EscapeAll
35
+ EscapeSingleQuoteAttr
38
36
}
39
37
40
38
impl < W : Writer > EscapeWriter < W > {
@@ -64,63 +62,24 @@ impl<W: Writer> EscapeWriter<W> {
64
62
65
63
impl < W : Writer > Writer for EscapeWriter < W > {
66
64
fn write ( & mut self , bytes : & [ u8 ] ) -> IoResult < ( ) > {
67
- if self . mode == EscapeAll {
68
- // This mode needs to operate on chars. Everything else is handled below.
69
- let s = str:: from_utf8_lossy ( bytes) ;
70
- let s = s. as_slice ( ) ;
71
- let mut last = 0 u;
72
- for ( i, c) in s. char_indices ( ) {
73
- match c {
74
- '&' |'<' |'>' |'"' |'\'' => ( ) ,
75
- '\0' | '\x20' ..'\x7E' => continue ,
76
- _ => ( )
77
- }
78
- if last < i {
79
- try!( self . inner . write_str ( s. slice ( last, i) ) ) ;
80
- }
81
- match c {
82
- '&' |'<' |'>' |'"' |'\'' => {
83
- let ent = match c {
84
- '&' => "&" ,
85
- '<' => "<" ,
86
- '>' => ">" ,
87
- '"' => """ ,
88
- '\'' => "'" ,
89
- _ => unreachable ! ( )
90
- } ;
91
- try!( self . inner . write_str ( ent) ) ;
92
- }
93
- _ => {
94
- let c = c as u32 ;
95
- try!( write ! ( & mut self . inner as & mut :: std:: io:: Writer , r"&\#x{:x};" , c) ) ;
96
- }
97
- }
98
- last = i + char:: len_utf8_bytes ( c) ;
99
- }
100
- if last < s. as_slice ( ) . len ( ) {
101
- try!( self . inner . write_str ( s. slice_from ( last) ) ) ;
102
- }
103
- } else {
104
- // We only want to escape ASCII values, so we can safely operate on bytes
105
- let mut last = 0 ;
106
- for ( i, b) in bytes. iter ( ) . enumerate ( ) {
107
- let ent = match ( self . mode , * b as char ) {
108
- ( _, '&' ) => "&" ,
109
- ( EscapeDefault , '<' ) |( EscapeText , '<' ) => "<" ,
110
- ( EscapeDefault , '>' ) |( EscapeText , '>' ) => ">" ,
111
- ( EscapeDefault , '\'' ) |( EscapeSingleQuoteAttr , '\'' ) => "'" ,
112
- ( EscapeDefault , '"' ) |( EscapeAttr , '"' ) => """ ,
113
- _ => continue
114
- } ;
115
- if last < i {
116
- try!( self . inner . write ( bytes. slice ( last, i) ) ) ;
117
- }
118
- try!( self . inner . write_str ( ent) ) ;
119
- last = i + 1 ;
120
- }
121
- if last < bytes. len ( ) {
122
- try!( self . inner . write ( bytes. slice_from ( last) ) ) ;
65
+ let mut last = 0 ;
66
+ for ( i, b) in bytes. iter ( ) . enumerate ( ) {
67
+ let ent = match ( self . mode , * b as char ) {
68
+ ( _, '&' ) => "&" ,
69
+ ( EscapeDefault , '<' ) |( EscapeText , '<' ) => "<" ,
70
+ ( EscapeDefault , '>' ) |( EscapeText , '>' ) => ">" ,
71
+ ( EscapeDefault , '\'' ) |( EscapeSingleQuoteAttr , '\'' ) => "'" ,
72
+ ( EscapeDefault , '"' ) |( EscapeAttr , '"' ) => """ ,
73
+ _ => continue
74
+ } ;
75
+ if last < i {
76
+ try!( self . inner . write ( bytes. slice ( last, i) ) ) ;
123
77
}
78
+ try!( self . inner . write_str ( ent) ) ;
79
+ last = i + 1 ;
80
+ }
81
+ if last < bytes. len ( ) {
82
+ try!( self . inner . write ( bytes. slice_from ( last) ) ) ;
124
83
}
125
84
Ok ( ( ) )
126
85
}
0 commit comments