MCPcopy Create free account
hub / github.com/Vector35/binaryninja-api / ParseStringToStream

Method ParseStringToStream

rapidjson/reader.h:840–905  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

838 // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
839 template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
840 RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
841//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
842#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
843 static const char escape[256] = {
844 Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
845 Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
846 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
847 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
848 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
849 };
850#undef Z16
851//!@endcond
852
853 for (;;) {
854 // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
855 if (!(parseFlags & kParseValidateEncodingFlag))
856 ScanCopyUnescapedString(is, os);
857
858 Ch c = is.Peek();
859 if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
860 size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset
861 is.Take();
862 Ch e = is.Peek();
863 if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
864 is.Take();
865 os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
866 }
867 else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
868 is.Take();
869 unsigned codepoint = ParseHex4(is, escapeOffset);
870 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
871 if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
872 // Handle UTF-16 surrogate pair
873 if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
874 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
875 unsigned codepoint2 = ParseHex4(is, escapeOffset);
876 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
877 if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
878 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
879 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
880 }
881 TEncoding::Encode(os, codepoint);
882 }
883 else
884 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);
885 }
886 else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote
887 is.Take();
888 os.Put('\0'); // null-terminate the string
889 return;
890 }
891 else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
892 if (c == '\0')
893 RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());
894 else
895 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell());
896 }
897 else {

Callers

nothing calls this directly

Calls 6

EncodeFunction · 0.85
ValidateFunction · 0.85
PeekMethod · 0.45
TellMethod · 0.45
TakeMethod · 0.45
PutMethod · 0.45

Tested by

no test coverage detected