Skip to content

Commit 3a0b8da

Browse files
committed
Merge pull request #101304 from Ivorforce/string-parse-ascii
Add `String::ascii` creator functions, to parse a char buffer as ASCII.
2 parents 2324805 + b6cfcde commit 3a0b8da

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

core/io/plist.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,16 @@ void PListNode::store_text(String &p_stream, uint8_t p_indent) const {
383383
p_stream += String("\t").repeat(p_indent);
384384
p_stream += "<data>\n";
385385
p_stream += String("\t").repeat(p_indent);
386-
p_stream += String(data_string.get_data()) + "\n";
386+
// Data should be Base64 (i.e. ASCII only).
387+
p_stream += String::ascii(data_string) + "\n";
387388
p_stream += String("\t").repeat(p_indent);
388389
p_stream += "</data>\n";
389390
} break;
390391
case PList::PLNodeType::PL_NODE_TYPE_DATE: {
391392
p_stream += String("\t").repeat(p_indent);
392393
p_stream += "<date>";
393-
p_stream += String(data_string.get_data());
394+
// Data should be ISO 8601 (i.e. ASCII only).
395+
p_stream += String::ascii(data_string);
394396
p_stream += "</date>\n";
395397
} break;
396398
case PList::PLNodeType::PL_NODE_TYPE_STRING: {

core/string/ustring.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,6 +1921,34 @@ CharString String::ascii(bool p_allow_extended) const {
19211921
return cs;
19221922
}
19231923

1924+
Error String::parse_ascii(const StrRange<char> &p_range) {
1925+
if (p_range.len == 0) {
1926+
resize(0);
1927+
return OK;
1928+
}
1929+
1930+
resize(p_range.len + 1); // Include \0
1931+
1932+
const char *src = p_range.c_str;
1933+
const char *end = src + p_range.len;
1934+
char32_t *dst = ptrw();
1935+
bool decode_failed = false;
1936+
1937+
for (; src < end; ++src, ++dst) {
1938+
// If char is int8_t, a set sign bit will be reinterpreted as 256 - val implicitly.
1939+
const uint8_t chr = *src;
1940+
if (chr > 127) {
1941+
print_unicode_error(vformat("Invalid ASCII codepoint (%x)", (uint32_t)chr), true);
1942+
decode_failed = true;
1943+
*dst = _replacement_char;
1944+
} else {
1945+
*dst = chr;
1946+
}
1947+
}
1948+
*dst = _null;
1949+
return decode_failed ? ERR_INVALID_DATA : OK;
1950+
}
1951+
19241952
String String::utf8(const char *p_utf8, int p_len) {
19251953
String ret;
19261954
ret.parse_utf8(p_utf8, p_len);

core/string/ustring.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,15 @@ class String {
518518
char32_t unicode_at(int p_idx) const;
519519

520520
CharString ascii(bool p_allow_extended = false) const;
521+
// Parse an ascii string.
522+
// If any character is > 127, an error will be logged, and 0xfffd will be inserted.
523+
Error parse_ascii(const StrRange<char> &p_range);
524+
static String ascii(const StrRange<char> &p_range) {
525+
String s;
526+
s.parse_ascii(p_range);
527+
return s;
528+
}
529+
521530
CharString utf8() const;
522531
Error parse_utf8(const char *p_utf8, int p_len = -1, bool p_skip_cr = false);
523532
Error parse_utf8(const StrRange<char> &p_range, bool p_skip_cr = false) {

0 commit comments

Comments
 (0)