Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Decompiler The decompiler engine itself
Projects
None yet
Development

No branches or pull requests

2 participants