| 292 | } // namespace |
| 293 | |
| 294 | inline void TBuf::WriteBareString(const TStringBuf s, EHtmlEscapeMode hem) { |
| 295 | RawWriteChar('"'); |
| 296 | const auto& specialChars = *Singleton<TFinder>(); |
| 297 | const char* b = s.begin(); |
| 298 | const char* e = s.end(); |
| 299 | const char* i = b; |
| 300 | while ((i = specialChars.FindFirstOf(i, e)) != e) { |
| 301 | // U+2028 (line separator) and U+2029 (paragraph separator) are valid string |
| 302 | // contents in JSON, but are treated as line breaks in JavaScript, breaking JSONP. |
| 303 | // In UTF-8, U+2028 is "\xe2\x80\xa8" and U+2029 is "\xe2\x80\xa9". |
| 304 | if (Y_UNLIKELY(e - i >= 3 && i[0] == '\xe2' && i[1] == '\x80' && (i[2] | 1) == '\xa9')) { |
| 305 | UnsafeWriteRawBytes(b, i - b); |
| 306 | UnsafeWriteRawBytes(i[2] == '\xa9' ? "\\u2029" : "\\u2028", 6); |
| 307 | b = i = i + 3; |
| 308 | } else if (EscapedWriteChar(b, i, hem)) { |
| 309 | b = ++i; |
| 310 | } else { |
| 311 | ++i; |
| 312 | } |
| 313 | } |
| 314 | UnsafeWriteRawBytes(b, e - b); |
| 315 | RawWriteChar('"'); |
| 316 | } |
| 317 | |
| 318 | inline void TBuf::RawWriteChar(char c) { |
| 319 | Stream->Write(c); |
nothing calls this directly
no test coverage detected