Check C# strings against UTF8 bytes instead of clamping (#221)

This commit is contained in:
Mason Sciotti 2018-08-16 11:23:28 -07:00 committed by GitHub
parent 3d3ae7129d
commit af380116a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -129,20 +129,20 @@ public class DiscordRpc
FreeMem(); FreeMem();
} }
_presence.state = StrToPtr(state, 128); _presence.state = StrToPtr(state);
_presence.details = StrToPtr(details, 128); _presence.details = StrToPtr(details);
_presence.startTimestamp = startTimestamp; _presence.startTimestamp = startTimestamp;
_presence.endTimestamp = endTimestamp; _presence.endTimestamp = endTimestamp;
_presence.largeImageKey = StrToPtr(largeImageKey, 32); _presence.largeImageKey = StrToPtr(largeImageKey);
_presence.largeImageText = StrToPtr(largeImageText, 128); _presence.largeImageText = StrToPtr(largeImageText);
_presence.smallImageKey = StrToPtr(smallImageKey, 32); _presence.smallImageKey = StrToPtr(smallImageKey);
_presence.smallImageText = StrToPtr(smallImageText, 128); _presence.smallImageText = StrToPtr(smallImageText);
_presence.partyId = StrToPtr(partyId, 128); _presence.partyId = StrToPtr(partyId);
_presence.partySize = partySize; _presence.partySize = partySize;
_presence.partyMax = partyMax; _presence.partyMax = partyMax;
_presence.matchSecret = StrToPtr(matchSecret, 128); _presence.matchSecret = StrToPtr(matchSecret);
_presence.joinSecret = StrToPtr(joinSecret, 128); _presence.joinSecret = StrToPtr(joinSecret);
_presence.spectateSecret = StrToPtr(spectateSecret, 128); _presence.spectateSecret = StrToPtr(spectateSecret);
_presence.instance = instance; _presence.instance = instance;
return _presence; return _presence;
@ -152,16 +152,18 @@ public class DiscordRpc
/// Returns a pointer to a representation of the given string with a size of maxbytes /// Returns a pointer to a representation of the given string with a size of maxbytes
/// </summary> /// </summary>
/// <param name="input">String to convert</param> /// <param name="input">String to convert</param>
/// <param name="maxbytes">Max number of bytes to use</param>
/// <returns>Pointer to the UTF-8 representation of <see cref="input"/></returns> /// <returns>Pointer to the UTF-8 representation of <see cref="input"/></returns>
private IntPtr StrToPtr(string input, int maxbytes) private IntPtr StrToPtr(string input)
{ {
if (string.IsNullOrEmpty(input)) return IntPtr.Zero; if (string.IsNullOrEmpty(input)) return IntPtr.Zero;
var convstr = StrClampBytes(input, maxbytes); var convbytecnt = Encoding.UTF8.GetByteCount(input);
var convbytecnt = Encoding.UTF8.GetByteCount(convstr); var buffer = Marshal.AllocHGlobal(convbytecnt + 1);
var buffer = Marshal.AllocHGlobal(convbytecnt); for (int i = 0; i < convbytecnt + 1; i++)
{
Marshal.WriteByte(buffer, i , 0);
}
_buffers.Add(buffer); _buffers.Add(buffer);
Marshal.Copy(Encoding.UTF8.GetBytes(convstr), 0, buffer, convbytecnt); Marshal.Copy(Encoding.UTF8.GetBytes(input), 0, buffer, convbytecnt);
return buffer; return buffer;
} }
@ -181,30 +183,6 @@ public class DiscordRpc
return Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(str)); return Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(str));
} }
/// <summary>
/// Clamp the string to the given byte length preserving null termination
/// </summary>
/// <param name="toclamp">string to clamp</param>
/// <param name="maxbytes">max bytes the resulting string should have (including null termination)</param>
/// <returns>null terminated string with a byte length less or equal to <see cref="maxbytes"/></returns>
private static string StrClampBytes(string toclamp, int maxbytes)
{
var str = StrToUtf8NullTerm(toclamp);
var strbytes = Encoding.UTF8.GetBytes(str);
if (strbytes.Length <= maxbytes)
{
return str;
}
var newstrbytes = new byte[] { };
Array.Copy(strbytes, 0, newstrbytes, 0, maxbytes - 1);
newstrbytes[newstrbytes.Length - 1] = 0;
newstrbytes[newstrbytes.Length - 2] = 0;
return Encoding.UTF8.GetString(newstrbytes);
}
/// <summary> /// <summary>
/// Free the allocated memory for conversion to <see cref="RichPresenceStruct"/> /// Free the allocated memory for conversion to <see cref="RichPresenceStruct"/>
/// </summary> /// </summary>