dnSpyEx / dnSpy

Unofficial revival of the well known .NET debugger and assembly editor, dnSpy
GNU General Public License v3.0
7.02k stars 462 forks source link

Error when trying to disassemble BAML files for culture different than “en-US” #282

Closed przemo20 closed 10 months ago

przemo20 commented 10 months ago

dnSpyEx version

6.5.0-rc1

Describe the Bug

dnSpyEx throws an error when trying to decompile a BAML file for a language other than English (en-US).

How To Reproduce

Example files: Borderlands 2 — Win32.zip (from the Borderlands 2 game)

  1. Open the Launcher.resources.dll file from the “de-DE” folder in dnSpyEx
  2. In the dnSpyEx window go to (expand): Launcher.resources → Launcher.resources.dll → Resources → Launcher.g.de-DE.resources and click on the mainwindow.baml file

Expected Behavior

dnSpyEx should disassembly the BAML file correctly.

Actual Behavior

dnSpyEx throws the following exception:

An error occurred
System.AggregateException: One or more errors occurred. (Value cannot be null. (Parameter 'ns'))
 ---> System.ArgumentNullException: Value cannot be null. (Parameter 'ns')
   at System.ArgumentNullException.Throw(String paramName)
   at System.ArgumentNullException.ThrowIfNull(Object argument, String paramName)
   at System.Xml.Linq.XElement.GetPrefixOfNamespace(XNamespace ns)
   at dnSpy.BamlDecompiler.Xaml.XamlProperty.ToMarkupExtensionName(XamlContext ctx, XElement parent, Boolean isFullName) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\Xaml\XamlProperty.cs:line 155
   at dnSpy.BamlDecompiler.Handlers.PropertyCustomHandler.Deserialize(XamlContext ctx, XElement elem, KnownTypes ser, Boolean isValueTypeId, Byte[] value) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\Handlers\Records\PropertyCustomHandler.cs:line 50
   at dnSpy.BamlDecompiler.Handlers.PropertyCustomHandler.Translate(XamlContext ctx, BamlNode node, BamlElement parent) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\Handlers\Records\PropertyCustomHandler.cs:line 161
   at dnSpy.BamlDecompiler.HandlerMap.ProcessChildren(XamlContext ctx, BamlBlockNode node, BamlElement nodeElem) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\IHandlers.cs:line 57
   at dnSpy.BamlDecompiler.Handlers.ElementHandler.Translate(XamlContext ctx, BamlNode node, BamlElement parent) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\Handlers\Blocks\ElementHandler.cs:line 41
   at dnSpy.BamlDecompiler.HandlerMap.ProcessChildren(XamlContext ctx, BamlBlockNode node, BamlElement nodeElem) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\IHandlers.cs:line 57
   at dnSpy.BamlDecompiler.Handlers.ElementHandler.Translate(XamlContext ctx, BamlNode node, BamlElement parent) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\Handlers\Blocks\ElementHandler.cs:line 41
   at dnSpy.BamlDecompiler.HandlerMap.ProcessChildren(XamlContext ctx, BamlBlockNode node, BamlElement nodeElem) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\IHandlers.cs:line 57
   at dnSpy.BamlDecompiler.Handlers.ElementHandler.Translate(XamlContext ctx, BamlNode node, BamlElement parent) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\Handlers\Blocks\ElementHandler.cs:line 41
   at dnSpy.BamlDecompiler.HandlerMap.ProcessChildren(XamlContext ctx, BamlBlockNode node, BamlElement nodeElem) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\IHandlers.cs:line 57
   at dnSpy.BamlDecompiler.Handlers.PropertyDictionaryHandler.Translate(XamlContext ctx, BamlNode node, BamlElement parent) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\Handlers\Blocks\PropertyDictionaryHandler.cs:line 40
   at dnSpy.BamlDecompiler.HandlerMap.ProcessChildren(XamlContext ctx, BamlBlockNode node, BamlElement nodeElem) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\IHandlers.cs:line 57
   at dnSpy.BamlDecompiler.Handlers.ElementHandler.Translate(XamlContext ctx, BamlNode node, BamlElement parent) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\Handlers\Blocks\ElementHandler.cs:line 41
   at dnSpy.BamlDecompiler.HandlerMap.ProcessChildren(XamlContext ctx, BamlBlockNode node, BamlElement nodeElem) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\IHandlers.cs:line 57
   at dnSpy.BamlDecompiler.Handlers.DocumentHandler.Translate(XamlContext ctx, BamlNode node, BamlElement parent) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\Handlers\Blocks\DocumentHandler.cs:line 34
   at dnSpy.BamlDecompiler.XamlDecompiler.Decompile(ModuleDef module, BamlDocument document, CancellationToken token, BamlDecompilerOptions bamlDecompilerOptions, List`1 assemblyReferences) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\XamlDecompiler.cs:line 45
   at dnSpy.BamlDecompiler.BamlResourceElementNode.Decompile(ModuleDef module, BamlDocument document, IDecompiler lang, IDecompilerOutput output, CancellationToken token) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\BamlResourceElementNode.cs:line 65
   at dnSpy.BamlDecompiler.BamlResourceElementNode.Decompile(IDecompilerOutput output, CancellationToken token) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\BamlResourceElementNode.cs:line 112
   at dnSpy.BamlDecompiler.BamlResourceElementNode.Decompile(IDecompileNodeContext context) in D:\a\dnSpy\dnSpy\Extensions\dnSpy.BamlDecompiler\BamlResourceElementNode.cs:line 100
   at dnSpy.Documents.Tabs.DocumentTreeNodeDecompiler.Decompile(IDecompileNodeContext decompileNodeContext, DocumentTreeNodeData[] nodes) in D:\a\dnSpy\dnSpy\dnSpy\dnSpy\Documents\Tabs\DocumentTreeNodeDecompiler.cs:line 53
   at dnSpy.Documents.Tabs.DocViewer.DecompileDocumentTabContent.CreateContentAsync(IAsyncShowContext ctx) in D:\a\dnSpy\dnSpy\dnSpy\dnSpy\Documents\Tabs\DocViewer\DecompileDocumentTabContent.cs:line 223
   at dnSpy.Documents.Tabs.TabContentImpl.<>c__DisplayClass51_0.<ShowInternal>b__0() in D:\a\dnSpy\dnSpy\dnSpy\dnSpy\Documents\Tabs\TabContentImpl.cs:line 345
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of inner exception stack trace ---

Additional Context

The original dnSpy doesn't have problems with disassembling these files; for some reason this doesn't work in dnSpyEx.

GazziFX commented 10 months ago

IIRC NET Core+ has separate package for globalization

Did you use dnSpy NET or NET Framework?

przemo20 commented 10 months ago

I tried both – the .NET Framework 4.8 and .NET 8.0 versions.

Though the error in the .NET Framework build is slightly different than that I posted in the bug report above.

.NET Framework: obraz

.NET 8.0: obraz

And here, on the other hand, how it looks on the original dnSpy: obraz

ElektroKill commented 10 months ago

Hello, the regression has been fixed and dnSpyEx now acts just like dnSpy in this case! A build containing a fix for the regression can be found here: https://github.com/dnSpyEx/dnSpy/actions/runs/7492991268