| 10924 | } |
| 10925 | |
| 10926 | void XmlEncode::encodeTo(std::ostream &os) const { |
| 10927 | // Apostrophe escaping not necessary if we always use " to write attributes |
| 10928 | // (see: http://www.w3.org/TR/xml/#syntax) |
| 10929 | |
| 10930 | for (std::size_t idx = 0; idx < m_str.size(); ++idx) { |
| 10931 | uchar c = m_str[idx]; |
| 10932 | switch (c) { |
| 10933 | case '<': |
| 10934 | os << "<"; |
| 10935 | break; |
| 10936 | case '&': |
| 10937 | os << "&"; |
| 10938 | break; |
| 10939 | |
| 10940 | case '>': |
| 10941 | // See: http://www.w3.org/TR/xml/#syntax |
| 10942 | if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') |
| 10943 | os << ">"; |
| 10944 | else |
| 10945 | os << c; |
| 10946 | break; |
| 10947 | |
| 10948 | case '\"': |
| 10949 | if (m_forWhat == ForAttributes) |
| 10950 | os << """; |
| 10951 | else |
| 10952 | os << c; |
| 10953 | break; |
| 10954 | |
| 10955 | default: |
| 10956 | // Check for control characters and invalid utf-8 |
| 10957 | |
| 10958 | // Escape control characters in standard ascii |
| 10959 | // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 |
| 10960 | if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { |
| 10961 | hexEscapeChar(os, c); |
| 10962 | break; |
| 10963 | } |
| 10964 | |
| 10965 | // Plain ASCII: Write it to stream |
| 10966 | if (c < 0x7F) { |
| 10967 | os << c; |
| 10968 | break; |
| 10969 | } |
| 10970 | |
| 10971 | // UTF-8 territory |
| 10972 | // Check if the encoding is valid and if it is not, hex escape bytes. |
| 10973 | // Important: We do not check the exact decoded values for validity, only the encoding format |
| 10974 | // First check that this bytes is a valid lead byte: |
| 10975 | // This means that it is not encoded as 1111 1XXX |
| 10976 | // Or as 10XX XXXX |
| 10977 | if (c < 0xC0 || c >= 0xF8) { |
| 10978 | hexEscapeChar(os, c); |
| 10979 | break; |
| 10980 | } |
| 10981 | |
| 10982 | auto encBytes = trailingBytes(c); |
| 10983 | // Are there enough bytes left to avoid accessing out-of-bounds memory? |
no test coverage detected