From 440502746a863429fe27922514072b05c4c69e79 Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Sun, 13 Aug 2017 17:03:20 +0100 Subject: [PATCH] Change BindingBase to use UTF8, not ASCII, strings From the OpenGL 4.6 core specification, section 22.2: String queries return pointers to UTF-8 encoded, null-terminated static strings describing properties of the current GL context. From the GLSL 4.6 specification, section 3.1: The source character set used for the OpenGL shading languages is Unicode in the UTF-8 encoding scheme. It used to be that strings were ASCII, but ASCII is a safe subset of UTF8 so any existing code that assumed strings were encoded as ASCII will continue to work. --- src/OpenTK/BindingsBase.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/OpenTK/BindingsBase.cs b/src/OpenTK/BindingsBase.cs index 807c0473..85fcfad3 100644 --- a/src/OpenTK/BindingsBase.cs +++ b/src/OpenTK/BindingsBase.cs @@ -72,10 +72,13 @@ namespace OpenTK protected abstract object SyncRoot { get; } /// - /// Marshals a pointer to a null-terminated byte array to the specified StringBuilder. + /// Marshals a pointer to a null-terminated byte array to a new System.String. /// This method supports OpenTK and is not intended to be called by user code. /// /// A pointer to a null-terminated byte array. + /// + /// A System.String with the data from . + /// protected static string MarshalPtrToString(IntPtr ptr) { if (ptr == IntPtr.Zero) @@ -93,13 +96,13 @@ namespace OpenTK ++str; } - return new string((sbyte*)ptr, 0, len, null); + return new string((sbyte*)ptr, 0, len, Encoding.UTF8); } } /// /// Marshal a System.String to unmanaged memory. - /// The resulting string is encoded in ASCII and must be freed + /// The resulting string is encoded in UTF8 and must be freed /// with FreeStringPtr. /// /// The System.String to marshal. @@ -118,20 +121,20 @@ namespace OpenTK // GetMaxByteCount() appears to allocate space for the final NUL // character, but allocate an extra one just in case (who knows // what old Mono version would do here.) - int max_count = Encoding.ASCII.GetMaxByteCount(str.Length) + 1; + int max_count = Encoding.UTF8.GetMaxByteCount(str.Length) + 1; IntPtr ptr = Marshal.AllocHGlobal(max_count); if (ptr == IntPtr.Zero) { throw new OutOfMemoryException(); } - // Pin the managed string and convert it to ASCII using - // the pointer overload of System.Encoding.ASCII.GetBytes(). + // Pin the managed string and convert it to UTF8 using + // the pointer overload of System.Encoding.UTF8.GetBytes(). unsafe { fixed (char* pstr = str) { - int actual_count = Encoding.ASCII.GetBytes(pstr, str.Length, (byte*)ptr, max_count); + int actual_count = Encoding.UTF8.GetBytes(pstr, str.Length, (byte*)ptr, max_count); Marshal.WriteByte(ptr, actual_count, 0); // Append '\0' at the end of the string return ptr; }