Unified bin to hex and hex to bin conversion

* Added new functions in WinPR
* Added unit tests for new functions
* Replaced existing (internal) conversion functions
This commit is contained in:
akallabeth 2021-04-19 10:06:14 +02:00 committed by akallabeth
parent 8cd61a01ff
commit 2ea7ac0c06
6 changed files with 398 additions and 119 deletions

View File

@ -713,73 +713,28 @@ fail:
BYTE* freerdp_assistance_hex_string_to_bin(const void* raw, size_t* size)
{
size_t length;
BYTE* buffer;
size_t i;
const char* str = (const char*)raw;
length = strlen(str);
if ((length % 2) != 0)
BYTE* buffer = NULL;
size_t length, rc;
if (!raw || !size)
return NULL;
length /= 2;
*size = length;
buffer = (BYTE*)malloc(length);
*size = 0;
length = strlen(raw);
buffer = calloc(length, sizeof(BYTE));
if (!buffer)
return NULL;
for (i = 0; i < length; i++)
rc = winpr_HexStringToBinBuffer(raw, length, buffer, length);
if (rc == 0)
{
int hn, ln;
char c;
hn = ln = 0;
c = str[(i * 2) + 0];
if ((c >= '0') && (c <= '9'))
hn = c - '0';
else if ((c >= 'a') && (c <= 'f'))
hn = (c - 'a') + 10;
else if ((c >= 'A') && (c <= 'F'))
hn = (c - 'A') + 10;
c = str[(i * 2) + 1];
if ((c >= '0') && (c <= '9'))
ln = c - '0';
else if ((c >= 'a') && (c <= 'f'))
ln = (c - 'a') + 10;
else if ((c >= 'A') && (c <= 'F'))
ln = (c - 'A') + 10;
buffer[i] = ((hn << 4) | ln) & 0xFF;
free(buffer);
return NULL;
}
*size = rc;
return buffer;
}
char* freerdp_assistance_bin_to_hex_string(const void* raw, size_t size)
{
size_t i;
char* p;
int ln, hn;
const char* data = (const char*)raw;
char bin2hex[] = "0123456789ABCDEF";
p = (char*)calloc((size + 1), 2);
if (!p)
return NULL;
for (i = 0; i < size; i++)
{
ln = data[i] & 0xF;
hn = (data[i] >> 4) & 0xF;
p[i * 2] = bin2hex[hn];
p[(i * 2) + 1] = bin2hex[ln];
}
p[size * 2] = '\0';
return p;
return winpr_BinToHexString(raw, size, FALSE);
}
int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* buffer, size_t size,

View File

@ -41,6 +41,11 @@ extern "C"
int width);
WINPR_API char* winpr_BinToHexString(const BYTE* data, size_t length, BOOL space);
WINPR_API size_t winpr_BinToHexStringBuffer(const BYTE* data, size_t length, char* dstStr,
size_t dstSize, BOOL space);
WINPR_API size_t winpr_HexStringToBinBuffer(const char* str, size_t strLength, BYTE* data,
size_t dataLength);
WINPR_API int wprintfx(const char* fmt, ...);
WINPR_API int wvprintfx(const char* fmt, va_list args);

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include <winpr/crt.h>
#include <winpr/error.h>
#include <winpr/print.h>
#include <winpr/windows.h>
/* Letters */
@ -94,32 +95,20 @@ static BYTE ru_Administrator_upper[] = "\xd0\x90\xd0\x94\xd0\x9c\xd0\x98\xd0\x9d
static void string_hexdump(const BYTE* data, size_t length)
{
const BYTE* p = data;
size_t i, line, offset = 0;
size_t offset = 0;
char* str = winpr_BinToHexString(data, length, TRUE);
if (!str)
return;
while (offset < length)
{
printf("%04" PRIxz " ", offset);
line = length - offset;
if (line > 16)
line = 16;
for (i = 0; i < line; i++)
printf("%02" PRIx8 " ", p[i]);
for (; i < 16; i++)
printf(" ");
for (i = 0; i < line; i++)
printf("%c", (p[i] >= 0x20 && p[i] < 0x7F) ? (char)p[i] : '.');
printf("\n");
offset += line;
p += line;
const size_t diff = (length - offset) * 3;
printf("%04" PRIxz " %.*s\n", offset, diff, &str[offset]);
offset += 16;
}
free(str);
}
static int convert_utf8_to_utf16(BYTE* lpMultiByteStr, BYTE* expected_lpWideCharStr,

View File

@ -33,6 +33,8 @@
#include "../log.h"
#define MIN(a, b) (a) < (b) ? (a) : (b)
void winpr_HexDump(const char* tag, UINT32 level, const BYTE* data, size_t length)
{
wLog* log = WLog_Get(tag);
@ -158,30 +160,92 @@ void winpr_CArrayDump(const char* tag, UINT32 level, const BYTE* data, int lengt
free(buffer);
}
static BYTE value(char c)
{
if ((c >= '0') && (c <= '9'))
return c - '0';
if ((c >= 'A') && (c <= 'F'))
return 10 + c - 'A';
if ((c >= 'a') && (c <= 'f'))
return 10 + c - 'a';
return 0;
}
size_t winpr_HexStringToBinBuffer(const char* str, size_t strLength, BYTE* data, size_t dataLength)
{
size_t x, y = 0;
size_t maxStrLen;
if (!str || !data || (strLength == 0) || (dataLength == 0))
return 0;
maxStrLen = strnlen(str, strLength);
for (x = 0; x < maxStrLen;)
{
BYTE val = value(str[x++]);
if (x < maxStrLen)
val = (val << 4) | (value(str[x++]));
if (x < maxStrLen)
{
if (str[x] == ' ')
x++;
}
data[y++] = val;
if (y >= dataLength)
return y;
}
return y;
}
size_t winpr_BinToHexStringBuffer(const BYTE* data, size_t length, char* dstStr, size_t dstSize,
BOOL space)
{
const size_t n = space ? 3 : 2;
const char bin2hex[] = "0123456789ABCDEF";
const size_t maxLength = MIN(length, dstSize / n);
size_t i;
if (!data || !dstStr || (length == 0) || (dstSize == 0))
return 0;
for (i = 0; i < maxLength; i++)
{
const int ln = data[i] & 0xF;
const int hn = (data[i] >> 4) & 0xF;
char* dst = &dstStr[i * n];
dst[0] = bin2hex[hn];
dst[1] = bin2hex[ln];
if (space)
dst[2] = ' ';
}
if (space && (maxLength > 0))
{
dstStr[maxLength * n - 1] = '\0';
return maxLength * n - 1;
}
dstStr[maxLength * n] = '\0';
return maxLength * n;
}
char* winpr_BinToHexString(const BYTE* data, size_t length, BOOL space)
{
size_t i;
int n;
char* p;
const char bin2hex[] = "0123456789ABCDEF";
n = space ? 3 : 2;
p = (char*)malloc((length + 1ULL) * n);
size_t rc;
const size_t n = space ? 3 : 2;
const size_t size = (length + 1ULL) * n;
char* p = (char*)malloc(size);
if (!p)
return NULL;
for (i = 0; i < length; i++)
rc = winpr_BinToHexStringBuffer(data, length, p, size, space);
if (rc == 0)
{
int ln = data[i] & 0xF;
int hn = (data[i] >> 4) & 0xF;
p[i * n] = bin2hex[hn];
p[(i * n) + 1] = bin2hex[ln];
if (space)
p[(i * n) + 2] = ' ';
free(p);
return NULL;
}
p[length * n] = '\0';
return p;
}

View File

@ -169,29 +169,6 @@ static void SamLookupFinish(WINPR_SAM* sam)
sam->line = NULL;
}
static void HexStrToBin(const char* str, BYTE* bin, size_t length)
{
size_t i;
CharUpperBuffA(str, length * 2);
for (i = 0; i < length; i++)
{
bin[i] = 0;
if ((str[i * 2] >= '0') && (str[i * 2] <= '9'))
bin[i] |= (str[i * 2] - '0') << 4;
if ((str[i * 2] >= 'A') && (str[i * 2] <= 'F'))
bin[i] |= (str[i * 2] - 'A' + 10) << 4;
if ((str[i * 2 + 1] >= '0') && (str[i * 2 + 1] <= '9'))
bin[i] |= (str[i * 2 + 1] - '0');
if ((str[i * 2 + 1] >= 'A') && (str[i * 2 + 1] <= 'F'))
bin[i] |= (str[i * 2 + 1] - 'A' + 10);
}
}
static BOOL SamReadEntry(WINPR_SAM* sam, WINPR_SAM_ENTRY* entry)
{
char* p[5];
@ -256,10 +233,10 @@ static BOOL SamReadEntry(WINPR_SAM* sam, WINPR_SAM_ENTRY* entry)
entry->Domain = NULL;
if (LmHashLength == 32)
HexStrToBin(p[2], (BYTE*)entry->LmHash, 16);
winpr_HexStringToBinBuffer(p[2], LmHashLength, entry->LmHash, sizeof(entry->LmHash));
if (NtHashLength == 32)
HexStrToBin(p[3], (BYTE*)entry->NtHash, 16);
winpr_HexStringToBinBuffer(p[3], NtHashLength, (BYTE*)entry->NtHash, sizeof(entry->NtHash));
return TRUE;
}

View File

@ -20,6 +20,289 @@
#define _printf wprintfx
#endif
static BOOL test_bin_tohex_string(void)
{
BOOL rc = FALSE;
{
const BYTE binbuffer[33] = { 0 };
const char empty[33] = { 0 };
char strbuffer[33] = { 0 };
size_t len =
winpr_BinToHexStringBuffer(NULL, sizeof(binbuffer), strbuffer, sizeof(strbuffer), TRUE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(binbuffer, 0, strbuffer, sizeof(strbuffer), TRUE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
len =
winpr_BinToHexStringBuffer(binbuffer, sizeof(binbuffer), NULL, sizeof(strbuffer), TRUE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(binbuffer, sizeof(binbuffer), strbuffer, 0, TRUE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(binbuffer, 0, strbuffer, 0, TRUE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(binbuffer, sizeof(binbuffer), NULL, 0, TRUE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(NULL, sizeof(binbuffer), strbuffer, 0, TRUE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(binbuffer, 0, NULL, 0, TRUE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(NULL, 0, NULL, 0, TRUE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(binbuffer, 0, NULL, 0, FALSE);
if (len != 0)
goto fail;
if (memcmp(strbuffer, empty, sizeof(strbuffer)) != 0)
goto fail;
}
{
const BYTE binbuffer1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
const char strbuffer1[] = "0102030405060708090A0B0C0D0E0F1011";
const char strbuffer1_space[] = "01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11";
char buffer[1024] = { 0 };
size_t len = winpr_BinToHexStringBuffer(binbuffer1, sizeof(binbuffer1), buffer,
sizeof(buffer), FALSE);
if (len != strnlen(strbuffer1, sizeof(strbuffer1)))
goto fail;
if (memcmp(strbuffer1, buffer, sizeof(strbuffer1)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(binbuffer1, sizeof(binbuffer1), buffer, sizeof(buffer),
TRUE);
if (len != strnlen(strbuffer1_space, sizeof(strbuffer1_space)))
goto fail;
if (memcmp(strbuffer1_space, buffer, sizeof(strbuffer1_space)) != 0)
goto fail;
}
{
const BYTE binbuffer1[] = { 0xF1, 0xe2, 0xD3, 0xc4, 0xB5, 0xA6, 0x97, 0x88, 0x79,
0x6A, 0x5b, 0x4C, 0x3d, 0x2E, 0x1f, 0x00, 0xfF };
const char strbuffer1[] = "F1E2D3C4B5A69788796A5B4C3D2E1F00FF";
const char strbuffer1_space[] = "F1 E2 D3 C4 B5 A6 97 88 79 6A 5B 4C 3D 2E 1F 00 FF";
char buffer[1024] = { 0 };
size_t len = winpr_BinToHexStringBuffer(binbuffer1, sizeof(binbuffer1), buffer,
sizeof(buffer), FALSE);
if (len != strnlen(strbuffer1, sizeof(strbuffer1)))
goto fail;
if (memcmp(strbuffer1, buffer, sizeof(strbuffer1)) != 0)
goto fail;
len = winpr_BinToHexStringBuffer(binbuffer1, sizeof(binbuffer1), buffer, sizeof(buffer),
TRUE);
if (len != strnlen(strbuffer1_space, sizeof(strbuffer1_space)))
goto fail;
if (memcmp(strbuffer1_space, buffer, sizeof(strbuffer1_space)) != 0)
goto fail;
}
{
}
rc = TRUE;
fail:
return rc;
}
static BOOL test_bin_tohex_string_alloc(void)
{
BOOL rc = FALSE;
char* str = NULL;
{
const BYTE binbuffer[33] = { 0 };
str = winpr_BinToHexString(NULL, sizeof(binbuffer), TRUE);
if (str)
goto fail;
str = winpr_BinToHexString(binbuffer, 0, TRUE);
if (str)
goto fail;
str = winpr_BinToHexString(binbuffer, 0, FALSE);
if (str)
goto fail;
str = winpr_BinToHexString(NULL, sizeof(binbuffer), FALSE);
if (str)
goto fail;
}
{
const BYTE binbuffer1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
const char strbuffer1[] = "0102030405060708090A0B0C0D0E0F1011";
const char strbuffer1_space[] = "01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11";
str = winpr_BinToHexString(binbuffer1, sizeof(binbuffer1), FALSE);
if (!str)
goto fail;
if (memcmp(strbuffer1, str, sizeof(strbuffer1)) != 0)
goto fail;
str = winpr_BinToHexString(binbuffer1, sizeof(binbuffer1), TRUE);
if (!str)
goto fail;
if (memcmp(strbuffer1_space, str, sizeof(strbuffer1_space)) != 0)
goto fail;
free(str);
str = NULL;
}
{
const BYTE binbuffer1[] = { 0xF1, 0xe2, 0xD3, 0xc4, 0xB5, 0xA6, 0x97, 0x88, 0x79,
0x6A, 0x5b, 0x4C, 0x3d, 0x2E, 0x1f, 0x00, 0xfF };
const char strbuffer1[] = "F1E2D3C4B5A69788796A5B4C3D2E1F00FF";
const char strbuffer1_space[] = "F1 E2 D3 C4 B5 A6 97 88 79 6A 5B 4C 3D 2E 1F 00 FF";
str = winpr_BinToHexString(binbuffer1, sizeof(binbuffer1), FALSE);
if (!str)
goto fail;
if (memcmp(strbuffer1, str, sizeof(strbuffer1)) != 0)
goto fail;
free(str);
str = winpr_BinToHexString(binbuffer1, sizeof(binbuffer1), TRUE);
if (!str)
goto fail;
if (memcmp(strbuffer1_space, str, sizeof(strbuffer1_space)) != 0)
goto fail;
free(str);
str = NULL;
}
rc = TRUE;
fail:
free(str);
return rc;
}
static BOOL test_hex_string_to_bin(void)
{
BOOL rc = FALSE;
{
const char stringbuffer[] = "123456789ABCDEFabcdef";
const BYTE empty[1024] = { 0 };
BYTE buffer[1024] = { 0 };
size_t len = winpr_HexStringToBinBuffer(NULL, 0, NULL, 0);
if (len != 0)
goto fail;
if (memcmp(buffer, empty, sizeof(buffer)) != 0)
goto fail;
len = winpr_HexStringToBinBuffer(NULL, sizeof(stringbuffer), buffer, sizeof(buffer));
if (len != 0)
goto fail;
if (memcmp(buffer, empty, sizeof(buffer)) != 0)
goto fail;
len = winpr_HexStringToBinBuffer(stringbuffer, 0, buffer, sizeof(buffer));
if (len != 0)
goto fail;
if (memcmp(buffer, empty, sizeof(buffer)) != 0)
goto fail;
len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), NULL, sizeof(buffer));
if (len != 0)
goto fail;
if (memcmp(buffer, empty, sizeof(buffer)) != 0)
goto fail;
len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, 0);
if (len != 0)
goto fail;
if (memcmp(buffer, empty, sizeof(buffer)) != 0)
goto fail;
}
{
const char stringbuffer[] = "123456789ABCDEF1abcdef";
const BYTE expected[] = {
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf1, 0xab, 0xcd, 0xef
};
BYTE buffer[32] = { 0 };
size_t len =
winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, sizeof(buffer));
if (len != sizeof(expected))
goto fail;
if (memcmp(buffer, expected, sizeof(expected)) != 0)
goto fail;
len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer,
sizeof(expected) / 2);
if (len != sizeof(expected) / 2)
goto fail;
if (memcmp(buffer, expected, sizeof(expected) / 2) != 0)
goto fail;
}
{
const char stringbuffer[] = "12 34 56 78 9A BC DE F1 ab cd ef";
const BYTE expected[] = {
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf1, 0xab, 0xcd, 0xef
};
BYTE buffer[1024] = { 0 };
size_t len =
winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, sizeof(buffer));
if (len != sizeof(expected))
goto fail;
if (memcmp(buffer, expected, sizeof(expected)) != 0)
goto fail;
len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer,
sizeof(expected) / 2);
if (len != sizeof(expected) / 2)
goto fail;
if (memcmp(buffer, expected, sizeof(expected) / 2) != 0)
goto fail;
}
{
const char stringbuffer[] = "123456789ABCDEF1abcdef9";
const BYTE expected[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
0xde, 0xf1, 0xab, 0xcd, 0xef, 0x09 };
BYTE buffer[1024] = { 0 };
size_t len =
winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, sizeof(buffer));
if (len != sizeof(expected))
goto fail;
if (memcmp(buffer, expected, sizeof(expected)) != 0)
goto fail;
len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer,
sizeof(expected) / 2);
if (len != sizeof(expected) / 2)
goto fail;
if (memcmp(buffer, expected, sizeof(expected) / 2) != 0)
goto fail;
}
{
const char stringbuffer[] = "12 34 56 78 9A BC DE F1 ab cd ef 9";
const BYTE expected[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
0xde, 0xf1, 0xab, 0xcd, 0xef, 0x09 };
BYTE buffer[1024] = { 0 };
size_t len =
winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer, sizeof(buffer));
if (len != sizeof(expected))
goto fail;
if (memcmp(buffer, expected, sizeof(expected)) != 0)
goto fail;
len = winpr_HexStringToBinBuffer(stringbuffer, sizeof(stringbuffer), buffer,
sizeof(expected) / 2);
if (len != sizeof(expected) / 2)
goto fail;
if (memcmp(buffer, expected, sizeof(expected) / 2) != 0)
goto fail;
}
rc = TRUE;
fail:
return rc;
}
int TestPrint(int argc, char* argv[])
{
int a, b;
@ -105,5 +388,11 @@ int TestPrint(int argc, char* argv[])
_printf(":%15.10s:\n", "Hello, world!");
_printf(":%-15.10s:\n", "Hello, world!");
if (!test_bin_tohex_string())
return -1;
if (!test_bin_tohex_string_alloc())
return -1;
if (!test_hex_string_to_bin())
return -1;
return 0;
}