| 15188 | {} |
| 15189 | |
| 15190 | void XmlEncode::encodeTo( std::ostream& os ) const { |
| 15191 | // Apostrophe escaping not necessary if we always use " to write attributes |
| 15192 | // (see: http://www.w3.org/TR/xml/#syntax) |
| 15193 | |
| 15194 | for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { |
| 15195 | uchar c = m_str[idx]; |
| 15196 | switch (c) { |
| 15197 | case '<': os << "<"; break; |
| 15198 | case '&': os << "&"; break; |
| 15199 | |
| 15200 | case '>': |
| 15201 | // See: http://www.w3.org/TR/xml/#syntax |
| 15202 | if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') |
| 15203 | os << ">"; |
| 15204 | else |
| 15205 | os << c; |
| 15206 | break; |
| 15207 | |
| 15208 | case '\"': |
| 15209 | if (m_forWhat == ForAttributes) |
| 15210 | os << """; |
| 15211 | else |
| 15212 | os << c; |
| 15213 | break; |
| 15214 | |
| 15215 | default: |
| 15216 | // Check for control characters and invalid utf-8 |
| 15217 | |
| 15218 | // Escape control characters in standard ascii |
| 15219 | // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 |
| 15220 | if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { |
| 15221 | hexEscapeChar(os, c); |
| 15222 | break; |
| 15223 | } |
| 15224 | |
| 15225 | // Plain ASCII: Write it to stream |
| 15226 | if (c < 0x7F) { |
| 15227 | os << c; |
| 15228 | break; |
| 15229 | } |
| 15230 | |
| 15231 | // UTF-8 territory |
| 15232 | // Check if the encoding is valid and if it is not, hex escape bytes. |
| 15233 | // Important: We do not check the exact decoded values for validity, only the encoding format |
| 15234 | // First check that this bytes is a valid lead byte: |
| 15235 | // This means that it is not encoded as 1111 1XXX |
| 15236 | // Or as 10XX XXXX |
| 15237 | if (c < 0xC0 || |
| 15238 | c >= 0xF8) { |
| 15239 | hexEscapeChar(os, c); |
| 15240 | break; |
| 15241 | } |
| 15242 | |
| 15243 | auto encBytes = trailingBytes(c); |
| 15244 | // Are there enough bytes left to avoid accessing out-of-bounds memory? |
| 15245 | if (idx + encBytes - 1 >= m_str.size()) { |
| 15246 | hexEscapeChar(os, c); |
| 15247 | break; |
no test coverage detected