Index: System.Security/SecurityElement.cs =================================================================== --- System.Security/SecurityElement.cs (revision 88950) +++ System.Security/SecurityElement.cs (working copy) @@ -194,7 +194,7 @@ Locale.GetText ("Invalid XML string") + ": " + value); } - text = value; + text = Unescape (value); } } @@ -316,6 +316,44 @@ return sb.ToString (); } + private static string Unescape (string str) + { + StringBuilder sb; + + if (str == null) + return null; + + if (str.IndexOfAny (invalid_chars) == -1) + return str; + + sb = new StringBuilder (); + int len = str.Length; + + for (int i = 0; i < len; i++) { + char c = str [i]; + if (c == '&') { + int end = str.IndexOf (';', i + 1); + if (end < 0) + // invalid XML + throw new ArgumentException (String.Format ("Incomplete entity reference in {0}", str)); + switch (str.Substring (i, end - i)) { + case "lt": sb.Append ('<'); break; + case "gt": sb.Append ('>'); break; + case "quot": sb.Append ('"'); break; + case "apos": sb.Append ('\''); break; + case "amp": sb.Append ('&'); break; + default: + throw new ArgumentException (String.Format ("Cannot resolve entity reference in {0}", str)); + } + i = end; // skip + } + else + sb.Append (c); + } + + return sb.ToString (); + } + #if NET_2_0 public #else Index: Mono.Xml/SecurityParser.cs =================================================================== --- Mono.Xml/SecurityParser.cs (revision 88950) +++ Mono.Xml/SecurityParser.cs (working copy) @@ -101,7 +101,7 @@ public void OnChars (string ch) { - current.Text = ch; + current.Text = SecurityElement.Escape (ch); } public void OnEndParsing (SmallXmlParser parser) {} Index: Test/Microsoft.Win32/RegistryKeyTest.cs =================================================================== --- Test/Microsoft.Win32/RegistryKeyTest.cs (revision 88950) +++ Test/Microsoft.Win32/RegistryKeyTest.cs (working copy) @@ -2592,6 +2592,26 @@ } } + [Test] + public void EscapeRegistryValue () // bug #322839 + { + try { + using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey ("bug322839")) { + createdKey.SetValue ("Path", "/usr/lib/whatever"); + createdKey.SetValue ("Info", "!"); + } + + using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey ("bug322839")) { + string path = openedKey.GetValue ("Path") as string; + Assert.AreEqual ("/usr/lib/whatever", path, "#1"); + string info = openedKey.GetValue ("Info") as string; + Assert.AreEqual ("!", info, "#2"); + } + } finally { + Registry.CurrentUser.DeleteSubKeyTree ("bug322839"); + } + } + private bool RunningOnUnix { get { #if NET_2_0