-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
Calling GetName() on a System.Reflection.Assembly that is loaded from a byte stream will throw exception in Japanese locale #20968
Comments
Just to make sure I'm clear: would something like the following snippet fail on JP locale?
Does the assembly have to be emitted from managed code, or can I just use a random assembly to try and load? |
Yes it should presuming お is enough to cause the issue. I was only able to avoid error by saving the assembly outside of the path with Japanese characters and loading it from there. In my case the path that it worked from was just |
Sorry, I edited in a second question there: does the assembly have to be emitted from managed code, or can I just use a random assembly to try and load? |
I didn't test if it breaks on assemblies not emitted by the managed code, I can check on that. |
It seems to only happen with assemblies emitted from managed code, I tried with System.Collections.Immutable and it works. Also tried with a random dll with few dependencies that wasn't already needed by the project (DotZLib) and it did not break either. |
Is there anything that might be different between the two? The emitted dll is emitted from the latest version of Roslyn. I also ran into the same issue with an assembly created by Harmony which uses Mono.Cecil to create the assembly https://github.com/pardeike/Harmony/blob/master/Harmony/Internal/HarmonySharedState.cs#L78. |
Try a non-system assembly? There are a few differences between system and user-created assemblies. |
Oh you edited in that you tried that, apologies. Could you try compiling the same assembly (some simple hello world should be fine) with Roslyn and a standalone project, and then try loading both, to verify this holds true? If you still see the failure, upload them both here and I can take a look. |
I also just tried with Newtonsoft.Json and it loaded correctly. I'll try the the Roslyn vs standalone project now. |
I can't reproduce it with LoadFrom() any longer on the dll. I don't have the code I was initially using to test the LoadFrom with, I was probably using an old executable that was still executing the .Load() from the emitted bytes, apologies for the misleading test. Running Assembly.Load() on a byte[] loaded from a package dll via File.ReadAllBytes() fails, whereas running Assembly.LoadFrom on the dll path directly works. Tested with Newtonsoft.Json, a VS2017 compiled dll, and a Roslyn 3.9 compiled dll. |
Ah okay, gotcha. So something like the following should trigger it?
|
This also might be Windows-only, unless I'm missing something? Testing on my MacOS machine:
If you confirm that snippet should work, I'll switch the locale on my Windows VM and give that a try. |
On second thought, this might only happen with shift jis? Will try in a bit. Edit: nope :(
|
Hi, is there any solution to this yet? |
This isn't reproducible locally. Please specify mono version to try to repro locally. |
My desktop is using Japanese locale/language, so I can try it on there
later today. As I recall, this does repro without issue on master, or at
least did earlier this year.
2021年11月9日(火) 14:44 Sam Patel ***@***.***>:
… This isn't reproducible locally. Please specify mono version to try to
repro locally.
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#20968 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAYIODXNXRINSXRPAA6C4ULULF225ANCNFSM4ZWEQVXQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Still happens on nightly:
|
failed to reproduce on Windows 11 with Chinese locale and mono 6.12.0. But I met the same issue while using Unity. strange
|
Successfully reproduced. And after a few hours of debugging, I found that the root cause is in Line 174 in a791978
Which in Windows, the result of getcwd is NOT guaranteed to be UTF-8(and usually using system's locale). So that, any function who calls g_get_current_dir will get a melformed string and the encoding invariant would be broken.In pratice, two of victims is mono_assembly_request_open and mono_assembly_request_load_from (both of them depends on g_get_current_dir to canonicalize assembly's filename) and all managed api that depends on them, Assembly.Load(byte[]) in this case.
side note: Assembly assembly = Assembly.LoadFrom("./MonoTest.dll");
Console.WriteLine(assembly.EscapedCodeBase); // you will see the melformed encoded string
Console.WriteLine(assembly.GetName()); // Exception on GetName()! and
|
Steps to Reproduce
C:\Users\userドキュメント\Unity Projects\MonoTest\MonoTest\bin\Debug\MonoTest.exe
System.Reflection.Assembly.Load()
, and then call GetName() on the loaded assembly.cd "C:\Users\userドキュメント\Unity Projects\MonoTest\MonoTest\bin\Debug"
mono "C:\Users\userドキュメント\Unity Projects\MonoTest\MonoTest\bin\Debug\MonoTest.exe"
System.Reflection.RuntimeAssembly.get_code_base()
To run example, install dependencies listed in packages.config via nuget and compile Debug build in VS2017, presumably other build environments will work as well. The program is contained in Program.cs. The built exe is also included in the bin directory
MonoTest.zip
Current Behavior
Will throw an exception
System.ExecutionEngineException: String conversion error: Illegal byte sequence encounted in the input.
when GetName() is called on loaded assembly. Full stack trace included belowExpected Behavior
Prints the assembly name without throwing. The exact expected output of the program to the console is:
Also tested by just running the exe directly to use the .NET runtime and it works as expected:
Details
Mono actually works as expected if your working directory does not contain Japanese characters. Just executing the program from the Users root dir prints the expected output without errors
It is only when you make the working directory contain Japanese characters that the runtime-created assembly with no connection to the file system will somehow break:
This seemed odd since other assemblies that aren't runtime loaded work fine. So I tried saving the assembly to the same directory as the exe and then loading it from the file directly using
Assembly.LoadFrom()
and supplying the path to the assembly that I saved to disk as a .dll. This also threw the same exception, so it didn't seem like just loading the assembly from the disk works. Then why can most other system assemblies load properly and have GetName() called on them? At least in part, it seems like it's because most of the assemblies are actually stored in some directory without Japanese characters. If I saved the generated assembly to a directory outside the project in some directory that doesn't include Japanese characters, it loaded correctly without issue.The reason I don't use just
mono MonoTest.exe
here is because mono throws a fit for no reason, and I cannot find an encoding for the MONO_EXTERNAL_ENCODINGS that works. utf8, utf32, all naming variations of shift-jis throw the same error, and utf16 just hangs the program indefinitely:On which platforms did you notice this
[ ] macOS
[ ] Linux
[x] Windows
Version Used:
6.12.0, this issue was originally noticed in Unity 2018.4.20f1 and then reproduced in the latest stable version of Mono.
Stacktrace
The text was updated successfully, but these errors were encountered: