chunk: Add utility that compares the prefix of two chunks
Unlike chunk_compare() this first compares the prefix of two nonces, then falls back to comparing the length. This is basically intended to compare nonces as specified in RFC 7296: "Lowest" means an octet-by-octet comparison (instead of, for instance, comparing the nonces as large integers). In other words, start by comparing the first octet; if they're equal, move to the next octet, and so on. If you reach the end of one nonce, that nonce is the lower one.
This commit is contained in:
@@ -93,20 +93,24 @@ END_TEST
|
|||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
int result;
|
int result;
|
||||||
|
int result_prefix;
|
||||||
chunk_t a;
|
chunk_t a;
|
||||||
chunk_t b;
|
chunk_t b;
|
||||||
} compare_data[] = {
|
} compare_data[] = {
|
||||||
{ 0, { NULL, 0 }, { NULL, 0 }},
|
{ 0, 0, { NULL, 0 }, { NULL, 0 }},
|
||||||
{ 0, chunk_from_chars(0x00), chunk_from_chars(0x00)},
|
{ 0, 0, chunk_from_chars(0x00), chunk_from_chars(0x00)},
|
||||||
{-1, chunk_from_chars(0x00), chunk_from_chars(0x01)},
|
{-1, -1, chunk_from_chars(0x00), chunk_from_chars(0x01)},
|
||||||
{ 1, chunk_from_chars(0x01), chunk_from_chars(0x00)},
|
{ 1, 1, chunk_from_chars(0x01), chunk_from_chars(0x00)},
|
||||||
{ 0, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x00)},
|
{ 0, 0, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x00)},
|
||||||
{-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
|
{-1, -1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
|
||||||
{ 1, chunk_from_chars(0x00, 0x01), chunk_from_chars(0x00, 0x00)},
|
{ 1, 1, chunk_from_chars(0x00, 0x01), chunk_from_chars(0x00, 0x00)},
|
||||||
{-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x01, 0x00)},
|
{-1, -1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x01, 0x00)},
|
||||||
{ 1, chunk_from_chars(0x01, 0x00), chunk_from_chars(0x00, 0x00)},
|
{ 1, 1, chunk_from_chars(0x01, 0x00), chunk_from_chars(0x00, 0x00)},
|
||||||
{-1, chunk_from_chars(0xff), chunk_from_chars(0x00, 0x00)},
|
{-1, 1, chunk_from_chars(0xff), chunk_from_chars(0x00, 0x00)},
|
||||||
{ 1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0xff)},
|
{ 1, -1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0xff)},
|
||||||
|
{-1, -1, chunk_from_chars(0x01), chunk_from_chars(0xff, 0x00)},
|
||||||
|
{-1, -1, chunk_from_chars(0x01), chunk_from_chars(0x01, 0x00)},
|
||||||
|
{ 1, 1, chunk_from_chars(0x01, 0x00), chunk_from_chars(0x01)},
|
||||||
};
|
};
|
||||||
|
|
||||||
START_TEST(test_compare)
|
START_TEST(test_compare)
|
||||||
@@ -121,6 +125,18 @@ START_TEST(test_compare)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_compare_prefix)
|
||||||
|
{
|
||||||
|
int result, expected;
|
||||||
|
|
||||||
|
result = chunk_compare_prefix(compare_data[_i].a, compare_data[_i].b);
|
||||||
|
expected = compare_data[_i].result_prefix;
|
||||||
|
ck_assert((result == 0 && expected == 0) ||
|
||||||
|
(result < 0 && expected < 0) ||
|
||||||
|
(result > 0 && expected > 0));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* clear
|
* clear
|
||||||
*/
|
*/
|
||||||
@@ -1200,6 +1216,7 @@ Suite *chunk_suite_create()
|
|||||||
|
|
||||||
tc = tcase_create("chunk_compare");
|
tc = tcase_create("chunk_compare");
|
||||||
tcase_add_loop_test(tc, test_compare, 0, countof(compare_data));
|
tcase_add_loop_test(tc, test_compare, 0, countof(compare_data));
|
||||||
|
tcase_add_loop_test(tc, test_compare_prefix, 0, countof(compare_data));
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("clear");
|
tc = tcase_create("clear");
|
||||||
|
|||||||
@@ -816,15 +816,34 @@ chunk_t chunk_to_dec(chunk_t chunk, char *buf)
|
|||||||
int chunk_compare(chunk_t a, chunk_t b)
|
int chunk_compare(chunk_t a, chunk_t b)
|
||||||
{
|
{
|
||||||
int compare_len = a.len - b.len;
|
int compare_len = a.len - b.len;
|
||||||
int len = (compare_len < 0)? a.len : b.len;
|
int len = (compare_len < 0) ? a.len : b.len;
|
||||||
|
|
||||||
if (compare_len != 0 || len == 0)
|
if (compare_len != 0 || len == 0)
|
||||||
{
|
{
|
||||||
return compare_len;
|
return compare_len;
|
||||||
}
|
}
|
||||||
return memcmp(a.ptr, b.ptr, len);
|
return memcmp(a.ptr, b.ptr, len);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
int chunk_compare_prefix(chunk_t a, chunk_t b)
|
||||||
|
{
|
||||||
|
int cmp, compare_len = a.len - b.len;
|
||||||
|
int len = (compare_len < 0) ? a.len : b.len;
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
{
|
||||||
|
return compare_len;
|
||||||
|
}
|
||||||
|
cmp = memcmp(a.ptr, b.ptr, len);
|
||||||
|
if (!cmp)
|
||||||
|
{
|
||||||
|
return compare_len;
|
||||||
|
}
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
|
|||||||
@@ -331,11 +331,26 @@ static inline chunk_t chunk_skip_zero(chunk_t chunk)
|
|||||||
chunk_t chunk_copy_pad(chunk_t dst, chunk_t src, u_char chr);
|
chunk_t chunk_copy_pad(chunk_t dst, chunk_t src, u_char chr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two chunks, returns zero if a equals b
|
* Compare two chunks, returns zero if they are equal or negative/positive if
|
||||||
* or negative/positive if a is small/greater than b
|
* a is smaller/greater than b.
|
||||||
|
*
|
||||||
|
* Note that if the chunks are not of equal length, their prefix is not
|
||||||
|
* compared, only their lengths.
|
||||||
*/
|
*/
|
||||||
int chunk_compare(chunk_t a, chunk_t b);
|
int chunk_compare(chunk_t a, chunk_t b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two chunks, returns zero if they are equal or negative/positive if
|
||||||
|
* a is smaller/greater than b.
|
||||||
|
*
|
||||||
|
* Unlike chunk_compare(), this first compares the two chunks' prefix and only
|
||||||
|
* then falls back to comparing their lengths (shorter is "lower") if the
|
||||||
|
* prefix is equal.
|
||||||
|
*
|
||||||
|
* This can e.g. be used to compare nonces.
|
||||||
|
*/
|
||||||
|
int chunk_compare_prefix(chunk_t a, chunk_t b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two chunks for equality,
|
* Compare two chunks for equality,
|
||||||
* NULL chunks are never equal.
|
* NULL chunks are never equal.
|
||||||
|
|||||||
Reference in New Issue
Block a user