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