Fix TIO encoding bug

This commit is contained in:
TuxSH 2019-04-28 15:04:42 +02:00
parent 2927bd5aa3
commit 8b56098d64
3 changed files with 20 additions and 10 deletions

View File

@ -33,7 +33,7 @@
u8 GDB_ComputeChecksum(const char *packetData, u32 len); u8 GDB_ComputeChecksum(const char *packetData, u32 len);
void GDB_EncodeHex(char *dst, const void *src, u32 len); void GDB_EncodeHex(char *dst, const void *src, u32 len);
u32 GDB_DecodeHex(void *dst, const char *src, u32 len); u32 GDB_DecodeHex(void *dst, const char *src, u32 len);
u32 GDB_EscapeBinaryData(void *dst, const void *src, u32 len, u32 maxLen); u32 GDB_EscapeBinaryData(u32 *encodedCount, void *dst, const void *src, u32 len, u32 maxLen);
u32 GDB_UnescapeBinaryData(void *dst, const void *src, u32 len); u32 GDB_UnescapeBinaryData(void *dst, const void *src, u32 len);
const char *GDB_ParseIntegerList(u32 *dst, const char *src, u32 nb, char sep, char lastSep, u32 base, bool allowPrefix); const char *GDB_ParseIntegerList(u32 *dst, const char *src, u32 nb, char sep, char lastSep, u32 base, bool allowPrefix);
const char *GDB_ParseHexIntegerList(u32 *dst, const char *src, u32 nb, char lastSep); const char *GDB_ParseHexIntegerList(u32 *dst, const char *src, u32 nb, char lastSep);

View File

@ -75,15 +75,19 @@ u32 GDB_DecodeHex(void *dst, const char *src, u32 len)
return (!ok) ? i - 1 : i; return (!ok) ? i - 1 : i;
} }
u32 GDB_EscapeBinaryData(void *dst, const void *src, u32 len, u32 maxLen) u32 GDB_EscapeBinaryData(u32 *encodedCount, void *dst, const void *src, u32 len, u32 maxLen)
{ {
u8 *dst8 = (u8 *)dst; u8 *dst8 = (u8 *)dst;
const u8 *src8 = (const u8 *)src; const u8 *src8 = (const u8 *)src;
for(u32 i = 0; i < len && (u32)dst8 - (u32)dst < maxLen; i++) maxLen = maxLen >= len ? len : maxLen;
while((uintptr_t)dst8 < (uintptr_t)dst + maxLen)
{ {
if(*src8 == '$' || *src8 == '#' || *src8 == '}' || *src8 == '*') if(*src8 == '$' || *src8 == '#' || *src8 == '}' || *src8 == '*')
{ {
if ((uintptr_t)dst8 + 1 >= (uintptr_t)dst + maxLen)
break;
*dst8++ = '}'; *dst8++ = '}';
*dst8++ = *src8++ ^ 0x20; *dst8++ = *src8++ ^ 0x20;
} }
@ -91,7 +95,8 @@ u32 GDB_EscapeBinaryData(void *dst, const void *src, u32 len, u32 maxLen)
*dst8++ = *src8++; *dst8++ = *src8++;
} }
return dst8 - (u8 *)dst; *encodedCount = dst8 - (u8 *)dst;
return src8 - (u8 *)src;
} }
u32 GDB_UnescapeBinaryData(void *dst, const void *src, u32 len) u32 GDB_UnescapeBinaryData(void *dst, const void *src, u32 len)
@ -99,7 +104,7 @@ u32 GDB_UnescapeBinaryData(void *dst, const void *src, u32 len)
u8 *dst8 = (u8 *)dst; u8 *dst8 = (u8 *)dst;
const u8 *src8 = (const u8 *)src; const u8 *src8 = (const u8 *)src;
for(u32 i = 0; i < len; i++) while((uintptr_t)src8 < (uintptr_t)src + len)
{ {
if(*src8 == '}') if(*src8 == '}')
{ {

View File

@ -332,6 +332,7 @@ GDB_DECLARE_TIO_HANDLER(Close)
GDB_DECLARE_TIO_HANDLER(Read) GDB_DECLARE_TIO_HANDLER(Read)
{ {
// GDB, with it code quality we're all aware of, always ask to read GDB_BUF_LEN, even if the packet can't fit...
// "$F<num>;<data>#XX" // "$F<num>;<data>#XX"
char buf2[GDB_BUF_LEN - 4]; char buf2[GDB_BUF_LEN - 4];
u8 buf[sizeof(buf2) - 2 - 8]; u8 buf[sizeof(buf2) - 2 - 8];
@ -355,10 +356,13 @@ GDB_DECLARE_TIO_HANDLER(Read)
if (err != 0) if (err != 0)
return GDB_TioReplyErrno(ctx, err); return GDB_TioReplyErrno(ctx, err);
int pos = sprintf(buf2, "F%lx;", (u32)numRead); char hdr[16];
u32 actualCount = GDB_EscapeBinaryData(buf2 + pos, buf, (u32)numRead, sizeof(buf)); u32 encodedCount;
u32 actualCount = GDB_EscapeBinaryData(&encodedCount, buf2 + 10, buf, (u32)numRead, sizeof(buf));
sprintf(hdr, "F%08lx;", (u32)actualCount); // buffer might not fit the entire read data
memcpy(buf2, hdr, 10);
return GDB_SendPacket(ctx, buf2, pos + actualCount); return GDB_SendPacket(ctx, buf2, 10 + encodedCount);
} }
GDB_DECLARE_TIO_HANDLER(Write) GDB_DECLARE_TIO_HANDLER(Write)
@ -448,9 +452,10 @@ GDB_DECLARE_TIO_HANDLER(Stat)
GDB_TioMakeStructStat(&gdbStFinal, &gdbSt); GDB_TioMakeStructStat(&gdbStFinal, &gdbSt);
char buf[3 + 2 * sizeof(struct gdbhio_stat)] = "F0;"; char buf[3 + 2 * sizeof(struct gdbhio_stat)] = "F0;";
u32 actualCount = GDB_EscapeBinaryData(buf + 3, buf, sizeof(struct gdbhio_stat), 2 * sizeof(struct gdbhio_stat)); u32 encodedCount;
GDB_EscapeBinaryData(&encodedCount, buf + 3, buf, sizeof(struct gdbhio_stat), 2 * sizeof(struct gdbhio_stat));
return GDB_SendPacket(ctx, buf, 3 + actualCount); return GDB_SendPacket(ctx, buf, 3 + encodedCount);
} }
GDB_DECLARE_TIO_HANDLER(Unlink) GDB_DECLARE_TIO_HANDLER(Unlink)