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

Fixed gambling caused by incorrect marshal, updated assembly version #339

Closed
wants to merge 7 commits into from

Conversation

Akarinnnnn
Copy link
Contributor

@Akarinnnnn Akarinnnnn commented Feb 29, 2020

Gambling is caused by [MarshalAs(UnmanagedType.ByValTStr...
Changed it to [MarshalAs(UnmanagedType.ByValArray... and added a property to operate it

 Set framework version to .NET Standard 2.1
 Pack on build
 Update package version
update assembly version and nuget package version
@Akarinnnnn
Copy link
Contributor Author

This .NET Core project will also pack a Nuget package while building

@Akarinnnnn Akarinnnnn changed the title Improve flexibility of .NET Standard and fix gambling Fixed gambling caused by incorrect marshal, updated assembly version Apr 1, 2020
@rlabrecque
Copy link
Owner

Hey, thanks, I'll get to this soon! Definitely a good improvement, though I'll probably redo the marshalling part in Steamworks.NET-CodeGen to automatically do stub out the string <-> byte[] conversion code

@rlabrecque
Copy link
Owner

Could you check this out?

#347

We can't use Span because Unity doesn't support it yet. :(

Maybe #if Unity use this, otherwise use Span?

@Akarinnnnn
Copy link
Contributor Author

Could you check this out?
#347
We can't use Span because Unity doesn't support it yet. :(
Maybe #if Unity use this, otherwise use Span?

We don't need Span now.
By the way

--- a/Plugins/Steamworks.NET/InteropHelp.cs                                                                             
+++ b/Plugins/Steamworks.NET/InteropHelp.cs
@@ -74,7 +74,7 @@ namespace Steamworks {

                public static void StringToByteArrayUTF8(string str, byte[] outArrayBuffer, int outArrayBufferSize)
                {
-                       outArrayBuffer = new byte[outArrayBufferSize];
+                       //outArrayBuffer = new byte[outArrayBufferSize];
                        int length = Encoding.UTF8.GetBytes(str, 0, str.Length, outArrayBuffer, 0);
                        outArrayBuffer[length] = 0;
                }

outArrayBuffer should not be overriden, or our data won't written to correct buffer.

@rlabrecque
Copy link
Owner

I'm worried about two things: The \0, and also StringToByteArrayUTF8 writing more than outArrayBufferSize maybe?

@Akarinnnnn
Copy link
Contributor Author

Akarinnnnn commented Apr 13, 2020

I'm worried about two things: The \0, and also StringToByteArrayUTF8 writing more than outArrayBufferSize maybe?

> string str = "简体中文";
> str.Length
4
> byte[] buffer = new byte[20];
> buffer
byte[20] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
> StringToByteArrayUTF8(str, buffer, 0);
> buffer
byte[20] { 231, 174, 128, 228, 189, 147, 228, 184, 173, 230, 150, 135, 0, 0, 0, 0, 0, 0, 0, 0 }
> buffer[13] = 231;
> buffer[14] = 174;
> buffer[15] = 128;
> ByteArrayToStringUTF8(buffer)
"简体中文"
> 

\0 is there, nothing to worry about.

> byte[] buff2 = new byte[1];
> StringToByteArrayUTF8(str, buff2, 0);
System.ArgumentException: 输出字节缓冲区太小,无法包含编码后的数据,编码“Unicode (UTF-8)”的操作回退“System.Text.EncoderReplacementFallback”。
参数名: bytes
  + System.Text.Encoding.ThrowBytesOverflow()
  + System.Text.Encoding.ThrowBytesOverflow(System.Text.EncoderNLS, bool)
  + System.Text.UTF8Encoding.GetBytes(System.Char*, int, System.Byte*, int, System.Text.EncoderNLS)
  + System.Text.UTF8Encoding.GetBytes(string, int, int, byte[], int)
  + Submission#0.StringToByteArrayUTF8(string, byte[], int)

This shown us if you try to write to a buffer that not large enough, UTF8Encoding.GetBytes will throw an System.ArgumentException.

@yaakov-h
Copy link

You definitely need to write \0 or otherwise zero out the array when writing, otherwise you can land up with garbage from previous values.

> var buffer = new byte[20];
> var str = "12345";
> Encoding.UTF8.GetBytes(str, 0, str.Length, buffer, 0);
> Encoding.UTF8.GetString(buffer)
"12345\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
> str = "543";
> Encoding.UTF8.GetBytes(str, 0, str.Length, buffer, 0);
> Encoding.UTF8.GetString(buffer)
"54345\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
>

@Akarinnnnn
Copy link
Contributor Author

Akarinnnnn commented Apr 13, 2020

You definitely need to write \0 or otherwise zero out the array when writing, otherwise you can land up with garbage from previous values.

var buffer = new byte[20];
var str = "12345";
Encoding.UTF8.GetBytes(str, 0, str.Length, buffer, 0);
Encoding.UTF8.GetString(buffer)
"12345\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
str = "543";
Encoding.UTF8.GetBytes(str, 0, str.Length, buffer, 0);
Encoding.UTF8.GetString(buffer)
"54345\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"

Sloved, see My work.

Author: Fa鸽 <1207247008@qq.com>  2020-04-13 14:35:06
Committer: Fa鸽 <1207247008@qq.com>  2020-04-13 14:35:06
Parent: d804b61dc2a226d53a83f67ef808ea2a6054d998 (Fixed a bug)
Branches: remotes/origin/u8str-b, u8str-b
Follows: 13.0.0
Precedes: 

    Restrict \0

-------------------- Plugins/Steamworks.NET/InteropHelp.cs --------------------
index d3dcb71..e5d0365 100644
@@ -76,7 +76,13 @@ namespace Steamworks {
 		{
 			//outArrayBuffer = new byte[outArrayBufferSize];
 			int length = Encoding.UTF8.GetBytes(str, 0, str.Length, outArrayBuffer, 0);
-			outArrayBuffer[length] = 0;
+#if NETSTANDARD2_1
+			System.Index index = length >= outArrayBuffer.Length ? ^1 : length;
+#else
+			int index = length >= outArrayBuffer.Length ? outArrayBuffer.Length - 1 : length;
+#endif
+			outArrayBuffer[index] = 0;
+			//outArrayBuffer[] = 0;
 		}
 
 		// This is for 'const char *' arguments which we need to ensure do not get GC'd while Steam is using them.

@rlabrecque
Copy link
Owner

Yeah I think that's looking better.

		public static void StringToByteArrayUTF8(string str, byte[] outArrayBuffer, int outArrayBufferSize)
		{
			int length = Encoding.UTF8.GetBytes(str, 0, str.Length, outArrayBuffer, 0);
#if NETSTANDARD2_1
			System.Index index = length >= outArrayBuffer.Length ? ^1 : length;
#else
			int index = length >= outArrayBuffer.Length ? outArrayBuffer.Length - 1 : length;
#endif
			outArrayBuffer[index] = 0;
		}

@yaakov-h ? ^

@Akarinnnnn Akarinnnnn closed this Jun 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants