diff --git a/bin/llvm-krun b/bin/llvm-krun index 6095401f6..a27aea80f 100755 --- a/bin/llvm-krun +++ b/bin/llvm-krun @@ -9,6 +9,7 @@ expanded_input_file="$(mktemp tmp.in.XXXXXXXXXX)" parser_file="$(mktemp tmp.parse.XXXXXXXXXX)" temp_inputs=() +# shellcheck disable=SC2329 cleanup () { # shellcheck disable=SC2317 rm -rf "$input_file" "$expanded_input_file" "$output_file" "$parser_file" "${temp_inputs[@]}" diff --git a/runtime/strings/bytes.cpp b/runtime/strings/bytes.cpp index 93aee9a15..4737228ed 100644 --- a/runtime/strings/bytes.cpp +++ b/runtime/strings/bytes.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -162,6 +163,24 @@ SortBytes hook_BYTES_string2bytes(SortString s) { return hook_BYTES_bytes2string(s); } +// Convert a bytes array to its hexadecimal string representation +// For example, the bytes array b'\x01\xef' becomes the string "01ef" +// syntax String ::= Bytes2Hex( Bytes ) +SortString hook_BYTES_bytes2hex(SortBytes b) { + static const std::array hexchars + = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + auto len_b = len(b); + auto *result + = static_cast(kore_alloc_token(sizeof(string) + len_b * 2)); + for (size_t i = 0; i < len_b; i++) { + result->data[i * 2] = hexchars.at((b->data[i] >> 4) & 0xf); + result->data[i * 2 + 1] = hexchars.at(b->data[i] & 0xf); + } + init_with_len(result, len_b * 2); + return result; +} + SortBytes hook_BYTES_substr(SortBytes input, SortInt start, SortInt end) { uint64_t ustart = GET_UI(start); uint64_t uend = GET_UI(end); diff --git a/unittests/runtime-strings/bytestest.cpp b/unittests/runtime-strings/bytestest.cpp index 42ecaa216..d334b14b3 100644 --- a/unittests/runtime-strings/bytestest.cpp +++ b/unittests/runtime-strings/bytestest.cpp @@ -20,6 +20,7 @@ mpz_ptr hook_BYTES_bytes2int(string *b, uint64_t endianness, uint64_t signedness); string *hook_BYTES_int2bytes(mpz_t len, mpz_t i, uint64_t endianness); string *hook_BYTES_bytes2string(string *b); +string *hook_BYTES_bytes2hex(string *b); string *hook_BYTES_string2bytes(string *s); string *hook_BYTES_substr(string *b, mpz_t start, mpz_t end); string *hook_BYTES_replaceAt(string *b, mpz_t start, string *b2); @@ -171,6 +172,19 @@ BOOST_AUTO_TEST_CASE(bytes2string) { BOOST_CHECK_EQUAL(0, memcmp(_1234->data, "1234", 4)); } +BOOST_AUTO_TEST_CASE(bytes2hex) { + auto empty = make_string(""); + auto res = hook_BYTES_bytes2hex(empty); + BOOST_CHECK(res != empty); + BOOST_CHECK_EQUAL(len(res), 0); + + auto _01ef = make_string("\x01\xef", 2); + res = hook_BYTES_bytes2hex(_01ef); + BOOST_CHECK(res != _01ef); + BOOST_CHECK_EQUAL(len(res), 4); + BOOST_CHECK_EQUAL(0, memcmp(res->data, "01ef", 4)); +} + BOOST_AUTO_TEST_CASE(string2bytes) { auto empty = make_string(""); auto res = hook_BYTES_string2bytes(empty);