Skip to content

Commit 79744f6

Browse files
authored
[generator] Fix for fixing invalid annotation XML. (dotnet#897)
Fixes: dotnet#883 Due to invalid XML provided in Google's `annotations.zip` file, we run it through the more forgiving `HtmlAgilityPack` (4073f3e) to attempt to fix it to valid XML. However, given this snippet: <item name="android.accounts.AccountManager android.accounts.AccountManagerFuture&lt;android.os.Bundle&gt; addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)"> <annotation name="androidx.annotation.RequiresPermission"> <val name="value" val="&quot;android.permission.MANAGE_ACCOUNTS&quot;" /> <val name="apis" val="&quot;..22&quot;" /> </annotation> </item> The invalid unescaped `<` and `>` characters in the `//item/@name` attribute seem to tell `HtmlAgilityPack` not to expect any attribute strings to be properly escaped. Thus when it gets to the `//val/@val` attributes, it treats `&quot;` as unescaped as well, thinking we want to value to be the literal string `"&quot;"`. When it writes out the valid XML, it realizes it needs to escape the ampersand, and writes out `&amp;quot;`, which breaks our usage of these annotations. The fix is to "unescape" every `&quot;` to a `"` so that it will be escaped correctly when saved as valid XML.
1 parent 220b87f commit 79744f6

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

src/Xamarin.Android.Tools.AnnotationSupport/AndroidAnnotationsSupport.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ static Stream FixAnnotationXML (Stream s)
7070
if (doc.DocumentNode.FirstChild.InnerHtml.StartsWith ("<?xml", StringComparison.Ordinal))
7171
doc.DocumentNode.FirstChild.Remove ();
7272

73+
FixEscapedQuotes (doc.DocumentNode);
74+
7375
var ms = new MemoryStream ();
7476
var xs = new XmlWriterSettings {
7577
Encoding = new UTF8Encoding (false),
@@ -86,6 +88,18 @@ static Stream FixAnnotationXML (Stream s)
8688
return ms;
8789
}
8890

91+
static void FixEscapedQuotes (HtmlNode node)
92+
{
93+
// Quotation marks in attribute values are already escaped as '&quot;', however the Save ()
94+
// is interpreting them as the string '&quot;' and thinks it needs to escape the ampersand,
95+
// resulting in writing '&amp;quot;'. Here we "un-escape" the quotation mark,
96+
// so that Save () will escape it correctly as '&quot;'.
97+
foreach (var attr in node.Attributes)
98+
attr.Value = attr.Value.Replace ("&quot;", "\"");
99+
100+
foreach (var child in node.ChildNodes)
101+
FixEscapedQuotes (child);
102+
}
89103
#endregion
90104

91105
#region data loader

0 commit comments

Comments
 (0)