Skip to content

Commit

Permalink
(GH-1540) Fix - AutoUninstaller can't find escaped quotes
Browse files Browse the repository at this point in the history
The change made for GH-1505 caused the registry information to escape a
little too well, so some of the quotes and apostrophes were being saved
as `'` and `"`. When it came time for automatic uninstaller
to remove the software that was found in the snapshot, it didn't know
how to work with those escaped double quotes and gave up very quickly.

To fix this, don't escape those two items, but handle any that may have
already had this adjustment.
  • Loading branch information
ferventcoder committed May 4, 2018
1 parent f6841c9 commit dabcac8
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,55 @@ public void should_call_command_executor()
It.IsAny<bool>()),
Times.Once);
}
}

public class when_uninstall_string_has_ampersand_quot : AutomaticUninstallerServiceSpecsBase
{
private readonly string uninstallStringWithAmpersandQuot = @"&quot;C:\Program Files (x86)\WinDirStat\Uninstall.exe&quot; /SILENT";

public override void Context()
{
base.Context();
registryKeys.Clear();
registryKeys.Add(
new RegistryApplicationKey
{
DisplayName = expectedDisplayName,
InstallLocation = @"C:\Program Files (x86)\WinDirStat",
UninstallString = uninstallStringWithAmpersandQuot,
HasQuietUninstall = true,
KeyPath = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinDirStat",
InstallerType = installerType.InstallerType,
});
packageInformation.RegistrySnapshot = new Registry("123", registryKeys);
}

public override void Because()
{
MockLogger.LogMessagesToConsole = true;
service.run(packageResult, config);
}

[Fact]
public void should_call_get_package_information()
{
packageInfoService.Verify(s => s.get_package_information(It.IsAny<IPackage>()), Times.Once);
}

[Fact]
public void should_call_command_executor()
{
commandExecutor.Verify(
c =>
c.execute(
expectedUninstallString,
"/SILENT".trim_safe(),
It.IsAny<int>(),
It.IsAny<Action<object, DataReceivedEventArgs>>(),
It.IsAny<Action<object, DataReceivedEventArgs>>(),
It.IsAny<bool>()),
Times.Once);
}
}

public class when_uninstall_string_has_multiple_file_paths : AutomaticUninstallerServiceSpecsBase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static string get_value_as_string(this RegistryKey key, string name)

// Since it is possible that registry keys contain characters that are not valid
// in XML files, ensure that all content is escaped, prior to serialization
var escapedXml = System.Security.SecurityElement.Escape(key.GetValue(name).to_string());
var escapedXml = System.Security.SecurityElement.Escape(key.GetValue(name).to_string()).Replace("&quot;","\"").Replace("&apos;","'");

return escapedXml == null ? string.Empty : escapedXml.Replace("\0", string.Empty);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, P
}

// split on " /" and " -" for quite a bit more accuracy
IList<string> uninstallArgsSplit = key.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
IList<string> uninstallArgsSplit = key.UninstallString.to_string().Replace("&quot;","\"").Replace("&apos;","'").Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
var uninstallExe = uninstallArgsSplit.DefaultIfEmpty(string.Empty).FirstOrDefault().trim_safe();
if (uninstallExe.Count(u => u == '"') > 2)
{
Expand All @@ -159,7 +159,7 @@ public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, P
this.Log().Debug("Error splitting the uninstall string:{0} {1}".format_with(Environment.NewLine,ex.to_string()));
}
}
var uninstallArgs = key.UninstallString.to_string().Replace(uninstallExe.to_string(), string.Empty).trim_safe();
var uninstallArgs = key.UninstallString.to_string().Replace("&quot;", "\"").Replace("&apos;", "'").Replace(uninstallExe.to_string(), string.Empty).trim_safe();

uninstallExe = uninstallExe.remove_surrounding_quotes();
this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public ChocolateyPackageInformation get_package_information(IPackage package)
A corrupt .registry file exists at {0}.
Open this file in a text editor, and remove/escape any characters that
are regarded as illegal within XML strings not surrounded by CData.
These are typically the characters &, ', "", and `<`, `>`. Again, this
These are typically the characters &, `<`, and `>`. Again, this
is an XML document, so you will see many < and > characters, so just
focus exclusively in the string values not surrounded by CData. Once
these have been corrected, rename the .registry.bad file to .registry.
Expand Down

0 comments on commit dabcac8

Please sign in to comment.