diff --git a/core/io/plist.cpp b/core/io/plist.cpp index dd1e6dc439f6..0ef70b42133c 100644 --- a/core/io/plist.cpp +++ b/core/io/plist.cpp @@ -383,14 +383,16 @@ void PListNode::store_text(String &p_stream, uint8_t p_indent) const { p_stream += String("\t").repeat(p_indent); p_stream += "\n"; p_stream += String("\t").repeat(p_indent); - p_stream += String(data_string.get_data()) + "\n"; + // Data should be Base64 (i.e. ASCII only). + p_stream += String::ascii(data_string) + "\n"; p_stream += String("\t").repeat(p_indent); p_stream += "\n"; } break; case PList::PLNodeType::PL_NODE_TYPE_DATE: { p_stream += String("\t").repeat(p_indent); p_stream += ""; - p_stream += String(data_string.get_data()); + // Data should be ISO 8601 (i.e. ASCII only). + p_stream += String::ascii(data_string); p_stream += "\n"; } break; case PList::PLNodeType::PL_NODE_TYPE_STRING: { diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index be50b0b4e91d..24ed4bcdedb1 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1954,6 +1954,34 @@ CharString String::ascii(bool p_allow_extended) const { return cs; } +Error String::parse_ascii(const StrRange &p_range) { + if (p_range.len == 0) { + resize(0); + return OK; + } + + resize(p_range.len + 1); // Include \0 + + const char *src = p_range.c_str; + const char *end = src + p_range.len; + char32_t *dst = ptrw(); + bool decode_failed = false; + + for (; src < end; ++src, ++dst) { + // If char is int8_t, a set sign bit will be reinterpreted as 256 - val implicitly. + const uint8_t chr = *src; + if (chr > 127) { + print_unicode_error(vformat("Invalid ASCII codepoint (%x)", (uint32_t)chr), true); + decode_failed = true; + *dst = _replacement_char; + } else { + *dst = chr; + } + } + *dst = _null; + return decode_failed ? ERR_INVALID_DATA : OK; +} + String String::utf8(const char *p_utf8, int p_len) { String ret; ret.parse_utf8(p_utf8, p_len); diff --git a/core/string/ustring.h b/core/string/ustring.h index 7c405d740293..3bbe5bf6fade 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -519,6 +519,15 @@ class String { char32_t unicode_at(int p_idx) const; CharString ascii(bool p_allow_extended = false) const; + // Parse an ascii string. + // If any character is > 127, an error will be logged, and 0xfffd will be inserted. + Error parse_ascii(const StrRange &p_range); + static String ascii(const StrRange &p_range) { + String s; + s.parse_ascii(p_range); + return s; + } + CharString utf8() const; Error parse_utf8(const char *p_utf8, int p_len = -1, bool p_skip_cr = false); Error parse_utf8(const StrRange p_range, bool p_skip_cr = false) {