| 582 | #endif // !FLATBUFFERS_PREFER_PRINTF |
| 583 | |
| 584 | inline bool EscapeString(const char *s, size_t length, std::string *_text, |
| 585 | bool allow_non_utf8, bool natural_utf8) { |
| 586 | std::string &text = *_text; |
| 587 | text += "\""; |
| 588 | for (uoffset_t i = 0; i < length; i++) { |
| 589 | char c = s[i]; |
| 590 | switch (c) { |
| 591 | case '\n': text += "\\n"; break; |
| 592 | case '\t': text += "\\t"; break; |
| 593 | case '\r': text += "\\r"; break; |
| 594 | case '\b': text += "\\b"; break; |
| 595 | case '\f': text += "\\f"; break; |
| 596 | case '\"': text += "\\\""; break; |
| 597 | case '\\': text += "\\\\"; break; |
| 598 | default: |
| 599 | if (c >= ' ' && c <= '~') { |
| 600 | text += c; |
| 601 | } else { |
| 602 | // Not printable ASCII data. Let's see if it's valid UTF-8 first: |
| 603 | const char *utf8 = s + i; |
| 604 | int ucc = FromUTF8(&utf8); |
| 605 | if (ucc < 0) { |
| 606 | if (allow_non_utf8) { |
| 607 | text += "\\x"; |
| 608 | text += IntToStringHex(static_cast<uint8_t>(c), 2); |
| 609 | } else { |
| 610 | // There are two cases here: |
| 611 | // |
| 612 | // 1) We reached here by parsing an IDL file. In that case, |
| 613 | // we previously checked for non-UTF-8, so we shouldn't reach |
| 614 | // here. |
| 615 | // |
| 616 | // 2) We reached here by someone calling GenerateText() |
| 617 | // on a previously-serialized flatbuffer. The data might have |
| 618 | // non-UTF-8 Strings, or might be corrupt. |
| 619 | // |
| 620 | // In both cases, we have to give up and inform the caller |
| 621 | // they have no JSON. |
| 622 | return false; |
| 623 | } |
| 624 | } else { |
| 625 | if (natural_utf8) { |
| 626 | // utf8 points to past all utf-8 bytes parsed |
| 627 | text.append(s + i, static_cast<size_t>(utf8 - s - i)); |
| 628 | } else if (ucc <= 0xFFFF) { |
| 629 | // Parses as Unicode within JSON's \uXXXX range, so use that. |
| 630 | text += "\\u"; |
| 631 | text += IntToStringHex(ucc, 4); |
| 632 | } else if (ucc <= 0x10FFFF) { |
| 633 | // Encode Unicode SMP values to a surrogate pair using two \u |
| 634 | // escapes. |
| 635 | uint32_t base = ucc - 0x10000; |
| 636 | auto high_surrogate = (base >> 10) + 0xD800; |
| 637 | auto low_surrogate = (base & 0x03FF) + 0xDC00; |
| 638 | text += "\\u"; |
| 639 | text += IntToStringHex(high_surrogate, 4); |
| 640 | text += "\\u"; |
| 641 | text += IntToStringHex(low_surrogate, 4); |
no test coverage detected