Browse Source

i18n: Fix parsing of multiple escapes before quotes

See https://github.com/godotengine/godot/pull/37114#issuecomment-601463765
Thakee Nathees 5 years ago
parent
commit
8c3ad2af93
1 changed files with 12 additions and 3 deletions
  1. 12 3
      core/io/translation_loader_po.cpp

+ 12 - 3
core/io/translation_loader_po.cpp

@@ -118,17 +118,26 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
 		ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, RES(), f->get_path() + ":" + itos(line) + " Invalid line '" + l + "' while parsing: ");
 		ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, RES(), f->get_path() + ":" + itos(line) + " Invalid line '" + l + "' while parsing: ");
 
 
 		l = l.substr(1, l.length());
 		l = l.substr(1, l.length());
-		//find final quote
+		// Find final quote, ignoring escaped ones (\").
+		// The escape_next logic is necessary to properly parse things like \\"
+		// where the blackslash is the one being escaped, not the quote.
 		int end_pos = -1;
 		int end_pos = -1;
+		bool escape_next = false;
 		for (int i = 0; i < l.length(); i++) {
 		for (int i = 0; i < l.length(); i++) {
+			if (l[i] == '\\' && !escape_next) {
+				escape_next = true;
+				continue;
+			}
 
 
-			if (l[i] == '"' && (i == 0 || l[i - 1] != '\\')) {
+			if (l[i] == '"' && !escape_next) {
 				end_pos = i;
 				end_pos = i;
 				break;
 				break;
 			}
 			}
+
+			escape_next = false;
 		}
 		}
 
 
-		ERR_FAIL_COND_V_MSG(end_pos == -1, RES(), f->get_path() + ":" + itos(line) + " Expected '\"' at end of message while parsing file: ");
+		ERR_FAIL_COND_V_MSG(end_pos == -1, RES(), f->get_path() + ":" + itos(line) + ": Expected '\"' at end of message while parsing file.");
 
 
 		l = l.substr(0, end_pos);
 		l = l.substr(0, end_pos);
 		l = l.c_unescape();
 		l = l.c_unescape();