Selaa lähdekoodia

Merge pull request #101304 from Ivorforce/string-parse-ascii

Add `String::ascii` creator functions, to parse a char buffer as ASCII.
Thaddeus Crews 5 kuukautta sitten
vanhempi
commit
3a0b8da168
3 muutettua tiedostoa jossa 41 lisäystä ja 2 poistoa
  1. 4 2
      core/io/plist.cpp
  2. 28 0
      core/string/ustring.cpp
  3. 9 0
      core/string/ustring.h

+ 4 - 2
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 += "<data>\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 += "</data>\n";
 		} break;
 		case PList::PLNodeType::PL_NODE_TYPE_DATE: {
 			p_stream += String("\t").repeat(p_indent);
 			p_stream += "<date>";
-			p_stream += String(data_string.get_data());
+			// Data should be ISO 8601 (i.e. ASCII only).
+			p_stream += String::ascii(data_string);
 			p_stream += "</date>\n";
 		} break;
 		case PList::PLNodeType::PL_NODE_TYPE_STRING: {

+ 28 - 0
core/string/ustring.cpp

@@ -1921,6 +1921,34 @@ CharString String::ascii(bool p_allow_extended) const {
 	return cs;
 }
 
+Error String::parse_ascii(const StrRange<char> &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);

+ 9 - 0
core/string/ustring.h

@@ -518,6 +518,15 @@ public:
 	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<char> &p_range);
+	static String ascii(const StrRange<char> &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<char> &p_range, bool p_skip_cr = false) {