Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Goto statement mess produced instead of else if condition with return #2379

Closed
ElektroKill opened this issue Apr 28, 2021 · 1 comment
Closed
Labels
Bug Decompiler The decompiler engine itself

Comments

@ElektroKill
Copy link
Contributor

ElektroKill commented Apr 28, 2021

Input code

ILSpyTestCase.zip
Method: ILSpyTestCase.Program.DownloadPDB

Erroneous output

internal void DownloadPDB(string _symbolDirectory, Guid guid, uint age, string pdbName)
	{
		string text = guid.ToString("N").ToUpper();
		HttpWebRequest obj = (HttpWebRequest)WebRequest.Create($"http://msdl.microsoft.com/download/symbols/{pdbName}/{text}{age:X}/{pdbName}");
		obj.UserAgent = "Microsoft-Symbol-Server/10.0.10522.521";
		using HttpWebResponse httpWebResponse = (HttpWebResponse)obj.GetResponse();
		if (httpWebResponse.StatusCode != HttpStatusCode.OK)
		{
			throw new Exception($"Failed to download {pdbName} - {httpWebResponse.StatusCode}  {httpWebResponse.StatusDescription}");
		}
		string text2 = $"{_symbolDirectory}\\{pdbName}\\{text}{age:X}";
		string path = text2 + "\\" + pdbName;
		if (!Directory.Exists(text2))
		{
			Directory.CreateDirectory(text2);
			goto IL_00d9;
		}
		if (!File.Exists(path))
		{
			goto IL_00d9;
		}
		goto end_IL_0059;
		IL_00d9:
		using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
		{
			byte[] array = new byte[4096];
			int count;
			while ((count = httpWebResponse.GetResponseStream().Read(array, 0, array.Length)) > 0)
			{
				fileStream.Write(array, 0, count);
			}
		}
		end_IL_0059:;
	}

Original code:

internal void DownloadPDB(string _symbolDirectory, Guid guid, uint age, string pdbName) {
			string guidStr = guid.ToString("N").ToUpper();

			var webReq = (HttpWebRequest)WebRequest.Create(
				$"http://msdl.microsoft.com/download/symbols/{pdbName}/{guidStr}{age:X}/{pdbName}");
			webReq.UserAgent = "Microsoft-Symbol-Server/10.0.10522.521";
			using (var webResp = (HttpWebResponse)webReq.GetResponse()) {
				if (webResp.StatusCode != HttpStatusCode.OK)
					throw new Exception($"Failed to download {pdbName} - {webResp.StatusCode}  {webResp.StatusDescription}");

				string downloadDirectory = $"{_symbolDirectory}\\{pdbName}\\{guidStr}{age:X}";
				string pdbLocation = $"{downloadDirectory}\\{pdbName}";
				if (!Directory.Exists(downloadDirectory))
					Directory.CreateDirectory(downloadDirectory);
				else if (File.Exists(pdbLocation))
					return;

				using (var fileStream = new FileStream(pdbLocation, FileMode.Create, FileAccess.Write)) {
					int bytesRead;
					byte[] buffer = new byte[4096];
					while ((bytesRead = webResp.GetResponseStream().Read(buffer, 0, buffer.Length)) > 0) {
						fileStream.Write(buffer, 0, bytesRead);
					}
				}
			}
		}

Details

ILSpy version 7.0.0.6485-rc2
.NET version 4.8.4300.0

EDIT: it looks like this occurs in all versions starting from ILSpy 3. It decompiles correctly in ILSpy 2.4:
image

@ElektroKill ElektroKill added Bug Decompiler The decompiler engine itself labels Apr 28, 2021
@dgrunwald
Copy link
Member

dgrunwald commented May 26, 2021

The finally block from the outer using seems to stop ILSpy from detecting the return; as a potential early-exit.

The problem also reproduces with:

        internal void Issue2379(bool a, bool b)
        {
            try {
                if (a)
                    Console.WriteLine("a");
                else if (b)
                    return;

                Console.WriteLine("a || !b");
            } finally {
                Console.WriteLine("finally");
            }
        }

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 2, 2021
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
Bug Decompiler The decompiler engine itself
Projects
None yet
Development

No branches or pull requests

2 participants