From: Tobias Brunner Date: Mon, 8 Apr 2019 13:24:23 +0000 (+0200) Subject: chunk: Add helper to copy a chunk left-padded to a certain length X-Git-Tag: 5.8.0rc1~28^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a5a8f2bce220837afcf0294322d4bd99f6878c8b;p=thirdparty%2Fstrongswan.git chunk: Add helper to copy a chunk left-padded to a certain length --- diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c index fbfb3ff9f8..2f6b59f816 100644 --- a/src/libstrongswan/tests/suites/test_chunk.c +++ b/src/libstrongswan/tests/suites/test_chunk.c @@ -573,6 +573,40 @@ START_TEST(test_increment) } END_TEST +/******************************************************************************* + * chunk_copy_pad tests + */ + +static struct { + size_t len; + u_char chr; + chunk_t src; + chunk_t exp; +} copy_pad_data[] = { + {0, 0x00, { NULL, 0 }, { NULL, 0 }}, + {4, 0x00, { NULL, 0 }, chunk_from_chars(0x00,0x00,0x00,0x00)}, + {0, 0x00, chunk_from_chars(0x01), { NULL, 0 }}, + {1, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x01)}, + {2, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x00,0x01)}, + {3, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x00,0x00,0x01)}, + {4, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x00,0x00,0x00,0x01)}, + {4, 0x02, chunk_from_chars(0x01), chunk_from_chars(0x02,0x02,0x02,0x01)}, + {1, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x04)}, + {2, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x03,0x04)}, + {3, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x02,0x03,0x04)}, + {4, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x01,0x02,0x03,0x04)}, +}; + +START_TEST(test_copy_pad) +{ + chunk_t chunk; + + chunk = chunk_copy_pad(chunk_alloca(copy_pad_data[_i].len), + copy_pad_data[_i].src, copy_pad_data[_i].chr); + ck_assert_chunk_eq(chunk, copy_pad_data[_i].exp); +} +END_TEST + /******************************************************************************* * chunk_printable tests */ @@ -1076,6 +1110,10 @@ Suite *chunk_suite_create() tcase_add_loop_test(tc, test_increment, 0, countof(increment_data)); suite_add_tcase(s, tc); + tc = tcase_create("chunk_copy_pad"); + tcase_add_loop_test(tc, test_copy_pad, 0, countof(copy_pad_data)); + suite_add_tcase(s, tc); + tc = tcase_create("chunk_printable"); tcase_add_loop_test(tc, test_printable, 0, countof(printable_data)); tcase_add_loop_test(tc, test_printable_sanitize, 0, countof(printable_data)); diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c index 239353879d..919b695785 100644 --- a/src/libstrongswan/utils/chunk.c +++ b/src/libstrongswan/utils/chunk.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2013 Tobias Brunner + * Copyright (C) 2008-2019 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * HSR Hochschule fuer Technik Rapperswil @@ -752,6 +752,26 @@ bool chunk_increment(chunk_t chunk) return TRUE; } +/* + * Described in header + */ +chunk_t chunk_copy_pad(chunk_t dst, chunk_t src, u_char chr) +{ + if (dst.ptr) + { + if (dst.len > src.len) + { + memcpy(dst.ptr + dst.len - src.len, src.ptr, src.len); + memset(dst.ptr, chr, dst.len - src.len); + } + else + { + memcpy(dst.ptr, src.ptr + src.len - dst.len, dst.len); + } + } + return dst; +} + /** * Remove non-printable characters from a chunk. */ diff --git a/src/libstrongswan/utils/chunk.h b/src/libstrongswan/utils/chunk.h index 0dbe9dc806..ea1274668e 100644 --- a/src/libstrongswan/utils/chunk.h +++ b/src/libstrongswan/utils/chunk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2013 Tobias Brunner + * Copyright (C) 2008-2019 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * HSR Hochschule fuer Technik Rapperswil @@ -292,6 +292,16 @@ static inline chunk_t chunk_skip_zero(chunk_t chunk) return chunk; } +/** + * Copy the data from src to dst, left-padded with chr if dst is longer, + * otherwise data is copied truncated on the left. + * + * @param dst data is copied here + * @param src data is copied from here + * @param chr value to use for padding if necessary + * @return the destination chunk + */ +chunk_t chunk_copy_pad(chunk_t dst, chunk_t src, u_char chr); /** * Compare two chunks, returns zero if a equals b