Skip to content

Commit

Permalink
Merge pull request #349 from transifex/android_fix
Browse files Browse the repository at this point in the history
Android parser: Fix for escaping  character <
  • Loading branch information
foteinigk authored Jul 30, 2024
2 parents 426b7da + 5151c14 commit aa7e7f4
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 10 deletions.
43 changes: 33 additions & 10 deletions openformats/formats/android_unescaped.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from openformats.formats.android import AndroidHandler
from ..utils.xml import NewDumbXml as DumbXml


class AndroidUnescapedHandler(AndroidHandler):
def _create_string(self, name, text, comment, product, child, pluralized=False):
"""Creates a string and returns it. If empty string it returns None.
Expand Down Expand Up @@ -96,17 +95,19 @@ def escape(string):
string
)
except Exception as _:
return AndroidHandler.escape(string)
# Exception handling: If an error occurs during tag protection,
# escape all special characters. One case of these errors is the
# presence of '<' symbols without corresponding closing tags, causing
# parsing errors.
string = AndroidHandler.escape(string)
string = AndroidUnescapedHandler.escape_special_characters(string)
string = (
string.replace("<", "&lt;")
)
return string

string = AndroidHandler.escape(string)
string = (
string.replace("&", "&amp;")
.replace(">", "&gt;")
.replace("\n", "\\n")
.replace("\t", "\\t")
.replace("@", "\\@")
.replace("?", "\\?")
)
string = AndroidUnescapedHandler.escape_special_characters(string)
return AndroidUnescapedHandler._unprotect_inline_tags(string, protected_tags)

@staticmethod
Expand All @@ -121,3 +122,25 @@ def unescape(string):
.replace("&lt;", "<")
.replace("&amp;", "&")
)

@staticmethod
def escape_special_characters(string):
"""
Escapes special characters in the given string.
Note:
- The '<' character is not escaped intentionally to avoid interfering
with inline tags that need to be protected and unprotected separately.
:param string: The input string that needs special characters escaped.
:returns: str: The input string with special characters escaped.
"""
return (
string.replace("&", "&amp;")
.replace(">", "&gt;")
.replace("\n", "\\n")
.replace("\t", "\\t")
.replace("@", "\\@")
.replace("?", "\\?")
)
25 changes: 25 additions & 0 deletions openformats/tests/formats/android/test_android_unescaped.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,31 @@ def test_escape(self):
raw,
)

def test_escape_lt_character(self):
rich = '< 20 units'
raw = '&lt; 20 units'

self.assertEqual(
AndroidUnescapedHandler.escape(rich),
raw,
)

rich = '< 20 & > 50 units'
raw = '&lt; 20 &amp; &gt; 50 units'

self.assertEqual(
AndroidUnescapedHandler.escape(rich),
raw,
)

rich = '< 20 & > 50 units<xliff:g>test</xliff:g>'
raw = '&lt; 20 &amp; &gt; 50 units&lt;xliff:g&gt;test&lt;/xliff:g&gt;'

self.assertEqual(
AndroidUnescapedHandler.escape(rich),
raw,
)

def test_unescape(self):
rich = "&<>'\n\t@?" + '"'
raw = "&amp;&lt;&gt;\\'\\n\\t\\@\\?" + '\\"'
Expand Down

0 comments on commit aa7e7f4

Please sign in to comment.