Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/topic/robin/gh-1874-bytes-to-mac'
Browse files Browse the repository at this point in the history
* origin/topic/robin/gh-1874-bytes-to-mac:
  Optimize `spicy::bytes_to_hexstring` and `spicy::bytes_to_mac`.
  Add new library function `spicy::bytes_to_mac`.
  • Loading branch information
rsmmr committed Sep 30, 2024
2 parents 2b0eb03 + 916ae42 commit a49287e
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 14 deletions.
11 changes: 11 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
1.12.0-dev.122 | 2024-09-30 14:18:09 +0200

* GH-1874: Add new library function `spicy::bytes_to_mac`. (Robin Sommer, Corelight)

```
## Returns a bytes value rendered as a MAC address string (i.e., colon-separated hex bytes).
public function bytes_to_mac(value: bytes) : string;
```

* Optimize `spicy::bytes_to_hexstring` and `spicy::bytes_to_mac`. (Robin Sommer, Corelight)

1.12.0-dev.119 | 2024-09-30 13:37:10 +0200

* GH-1846: Fix bug with captures groups. (Robin Sommer, Corelight)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.12.0-dev.119
1.12.0-dev.122
6 changes: 6 additions & 0 deletions doc/autogen/spicy-functions.spicy
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ Constructs a time value from a tuple of broken-out elements specifying local tim

Returns a bytes value rendered as a hex string.

.. _spicy_bytes_to_mac:

.. rubric:: ``function spicy::bytes_to_mac(value: bytes) : string``

Returns a bytes value rendered as a MAC address string (i.e., colon-separated hex bytes).

.. _spicy_getenv:

.. rubric:: ``function spicy::getenv(name: string) : optional<string>``
Expand Down
3 changes: 3 additions & 0 deletions spicy/lib/spicy.spicy
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ public function mktime(y: uint64, m: uint64, d: uint64, H: uint64, M: uint64, S:
## Returns a bytes value rendered as a hex string.
public function bytes_to_hexstring(value: bytes) : string &cxxname="spicy::rt::bytes_to_hexstring" &have_prototype;

## Returns a bytes value rendered as a MAC address string (i.e., colon-separated hex bytes).
public function bytes_to_mac(value: bytes) : string &cxxname="spicy::rt::bytes_to_mac" &have_prototype;

## Returns the value of an environment variable, if set.
public function getenv(name: string) : optional<string> &cxxname="hilti::rt::getenv" &have_prototype;

Expand Down
3 changes: 3 additions & 0 deletions spicy/runtime/include/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ extern std::string version();
/** Returns a bytes value rendered as a hex string. */
extern std::string bytes_to_hexstring(const hilti::rt::Bytes& value);

/** Returns a bytes value rendered as a MAC address string. */
extern std::string bytes_to_mac(const hilti::rt::Bytes& value);

/** Returns the internal `__offsets` member if present. */
extern const hilti::rt::Vector<
std::optional<std::tuple<hilti::rt::integer::safe<uint64_t>, std::optional<hilti::rt::integer::safe<uint64_t>>>>>*
Expand Down
6 changes: 6 additions & 0 deletions spicy/runtime/src/tests/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ TEST_CASE("bytes_to_hexstring") {
CHECK_EQ(bytes_to_hexstring("\x01\x02\x03"_b), "010203");
}

TEST_CASE("bytes_to_mac") {
CHECK_EQ(bytes_to_mac(""_b), "");
CHECK_EQ(bytes_to_mac("\x01\x02\x0a"_b), "01:02:0A");
CHECK_EQ(bytes_to_mac("\x01"_b), "01");
}

TEST_CASE("version") { CHECK_FALSE(version().empty()); }

TEST_SUITE_END();
32 changes: 30 additions & 2 deletions spicy/runtime/src/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,39 @@ std::string spicy::rt::version() {
#endif
}


static inline void byte_to_hex(unsigned char byte, char* hex_out) {
static constexpr char hex_chars[] = "0123456789ABCDEF";
hex_out[0] = hex_chars[(byte & 0xf0) >> 4];
hex_out[1] = hex_chars[byte & 0x0f];
}

std::string spicy::rt::bytes_to_hexstring(const hilti::rt::Bytes& value) {
const auto& data = value.str();

if ( data.empty() )
return "";

std::string result;
result.resize(data.size() * 2); // 2 digits per hex byte

for ( unsigned long i = 0; i < data.size(); i++ )
byte_to_hex(data[i], &result[i * 2]);

return result;
}

std::string spicy::rt::bytes_to_mac(const hilti::rt::Bytes& value) {
const auto& data = value.str();

if ( data.empty() )
return "";

// Two digits per hex byte, plus one colon per byte except the last.
std::string result((data.size() * 2) + (data.size() - 1), ':');

for ( auto x : value )
result += hilti::rt::fmt("%02X", x);
for ( unsigned long i = 0; i < data.size(); i++ )
byte_to_hex(data[i], &result[i * 3]);

return result;
}
Expand Down
15 changes: 8 additions & 7 deletions tests/Baseline/spicy.types.function.cxxname-normalization/output
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,11 @@
[debug/resolver] [spicy.spicy:126:39-126:78] Attribute "&cxxname="hilti::rt::time::current_time"" -> Attribute "&cxxname="::hilti::rt::time::current_time""
[debug/resolver] [spicy.spicy:136:97-136:130] Attribute "&cxxname="hilti::rt::time::mktime"" -> Attribute "&cxxname="::hilti::rt::time::mktime""
[debug/resolver] [spicy.spicy:139:59-139:98] Attribute "&cxxname="spicy::rt::bytes_to_hexstring"" -> Attribute "&cxxname="::spicy::rt::bytes_to_hexstring""
[debug/resolver] [spicy.spicy:142:57-142:84] Attribute "&cxxname="hilti::rt::getenv"" -> Attribute "&cxxname="::hilti::rt::getenv""
[debug/resolver] [spicy.spicy:154:68-154:97] Attribute "&cxxname="hilti::rt::strftime"" -> Attribute "&cxxname="::hilti::rt::strftime""
[debug/resolver] [spicy.spicy:166:62-166:91] Attribute "&cxxname="hilti::rt::strptime"" -> Attribute "&cxxname="::hilti::rt::strptime""
[debug/resolver] [spicy.spicy:171:49-171:84] Attribute "&cxxname="hilti::rt::address::parse"" -> Attribute "&cxxname="::hilti::rt::address::parse""
[debug/resolver] [spicy.spicy:176:48-176:83] Attribute "&cxxname="hilti::rt::address::parse"" -> Attribute "&cxxname="::hilti::rt::address::parse""
[debug/resolver] [spicy.spicy:181:39-181:72] Attribute "&cxxname="spicy::rt::accept_input"" -> Attribute "&cxxname="::spicy::rt::accept_input""
[debug/resolver] [spicy.spicy:192:54-192:88] Attribute "&cxxname="spicy::rt::decline_input"" -> Attribute "&cxxname="::spicy::rt::decline_input""
[debug/resolver] [spicy.spicy:142:53-142:86] Attribute "&cxxname="spicy::rt::bytes_to_mac"" -> Attribute "&cxxname="::spicy::rt::bytes_to_mac""
[debug/resolver] [spicy.spicy:145:57-145:84] Attribute "&cxxname="hilti::rt::getenv"" -> Attribute "&cxxname="::hilti::rt::getenv""
[debug/resolver] [spicy.spicy:157:68-157:97] Attribute "&cxxname="hilti::rt::strftime"" -> Attribute "&cxxname="::hilti::rt::strftime""
[debug/resolver] [spicy.spicy:169:62-169:91] Attribute "&cxxname="hilti::rt::strptime"" -> Attribute "&cxxname="::hilti::rt::strptime""
[debug/resolver] [spicy.spicy:174:49-174:84] Attribute "&cxxname="hilti::rt::address::parse"" -> Attribute "&cxxname="::hilti::rt::address::parse""
[debug/resolver] [spicy.spicy:179:48-179:83] Attribute "&cxxname="hilti::rt::address::parse"" -> Attribute "&cxxname="::hilti::rt::address::parse""
[debug/resolver] [spicy.spicy:184:39-184:72] Attribute "&cxxname="spicy::rt::accept_input"" -> Attribute "&cxxname="::spicy::rt::accept_input""
[debug/resolver] [spicy.spicy:195:54-195:88] Attribute "&cxxname="spicy::rt::decline_input"" -> Attribute "&cxxname="::spicy::rt::decline_input""
10 changes: 8 additions & 2 deletions tests/Baseline/spicy.types.unit.canonical-ids-with-import/output
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@
[debug/ast-declarations] - Parameter "S" (spicy::S)
[debug/ast-declarations] - Function "bytes_to_hexstring" (spicy::bytes_to_hexstring)
[debug/ast-declarations] - Parameter "value" (spicy::value)
[debug/ast-declarations] - Function "bytes_to_mac" (spicy::bytes_to_mac)
[debug/ast-declarations] - Parameter "value" (spicy::value_2)
[debug/ast-declarations] - Function "getenv" (spicy::getenv)
[debug/ast-declarations] - Parameter "name" (spicy::name)
[debug/ast-declarations] - Function "strftime" (spicy::strftime)
Expand Down Expand Up @@ -384,7 +386,7 @@
[debug/ast-declarations] - [function] hilti::exception_where_2 -> hilti::Exception, hilti::RecoverableFailure
[debug/ast-declarations] - [function] hilti::profiler_start -> hilti::Profiler
[debug/ast-declarations] - [function] hilti::profiler_stop -> hilti::Profiler
[debug/ast-declarations] - [module] spicy -> spicy::AddressFamily, spicy::Base64Stream, spicy::BitOrder, spicy::ByteOrder, spicy::Charset, spicy::DecodeErrorStrategy, spicy::Direction, spicy::Error, spicy::MatchState, spicy::Protocol, spicy::RealType, spicy::ReassemblerPolicy, spicy::Side, spicy::StreamStatistics, spicy::ZlibStream, spicy::accept_input, spicy::base64_decode, spicy::base64_encode, spicy::base64_finish, spicy::bytes_to_hexstring, spicy::crc32_add, spicy::crc32_init, spicy::current_time, spicy::decline_input, spicy::getenv, spicy::mktime, spicy::parse_address, spicy::parse_address_2, spicy::strftime, spicy::strptime, spicy::zlib_decompress, spicy::zlib_finish, spicy::zlib_init
[debug/ast-declarations] - [module] spicy -> spicy::AddressFamily, spicy::Base64Stream, spicy::BitOrder, spicy::ByteOrder, spicy::Charset, spicy::DecodeErrorStrategy, spicy::Direction, spicy::Error, spicy::MatchState, spicy::Protocol, spicy::RealType, spicy::ReassemblerPolicy, spicy::Side, spicy::StreamStatistics, spicy::ZlibStream, spicy::accept_input, spicy::base64_decode, spicy::base64_encode, spicy::base64_finish, spicy::bytes_to_hexstring, spicy::bytes_to_mac, spicy::crc32_add, spicy::crc32_init, spicy::current_time, spicy::decline_input, spicy::getenv, spicy::mktime, spicy::parse_address, spicy::parse_address_2, spicy::strftime, spicy::strptime, spicy::zlib_decompress, spicy::zlib_finish, spicy::zlib_init
[debug/ast-declarations] - [function] spicy::base64_decode -> spicy::Base64Stream
[debug/ast-declarations] - [function] spicy::base64_encode -> spicy::Base64Stream
[debug/ast-declarations] - [function] spicy::base64_finish -> spicy::Base64Stream
Expand Down Expand Up @@ -914,6 +916,8 @@
[debug/ast-declarations] - Parameter "S" (spicy::S)
[debug/ast-declarations] - Function "bytes_to_hexstring" (spicy::bytes_to_hexstring)
[debug/ast-declarations] - Parameter "value" (spicy::value)
[debug/ast-declarations] - Function "bytes_to_mac" (spicy::bytes_to_mac)
[debug/ast-declarations] - Parameter "value" (spicy::value_2)
[debug/ast-declarations] - Function "getenv" (spicy::getenv)
[debug/ast-declarations] - Parameter "name" (spicy::name)
[debug/ast-declarations] - Function "strftime" (spicy::strftime)
Expand Down Expand Up @@ -1382,6 +1386,8 @@
[debug/ast-declarations] - Parameter "S" (spicy::S)
[debug/ast-declarations] - Function "bytes_to_hexstring" (spicy::bytes_to_hexstring)
[debug/ast-declarations] - Parameter "value" (spicy::value)
[debug/ast-declarations] - Function "bytes_to_mac" (spicy::bytes_to_mac)
[debug/ast-declarations] - Parameter "value" (spicy::value_2)
[debug/ast-declarations] - Function "getenv" (spicy::getenv)
[debug/ast-declarations] - Parameter "name" (spicy::name)
[debug/ast-declarations] - Function "strftime" (spicy::strftime)
Expand Down Expand Up @@ -1422,7 +1428,7 @@
[debug/ast-declarations] - [function] hilti::exception_where_2 -> hilti::Exception, hilti::RecoverableFailure
[debug/ast-declarations] - [function] hilti::profiler_start -> hilti::Profiler
[debug/ast-declarations] - [function] hilti::profiler_stop -> hilti::Profiler
[debug/ast-declarations] - [module] spicy -> spicy::AddressFamily, spicy::Base64Stream, spicy::BitOrder, spicy::ByteOrder, spicy::Charset, spicy::DecodeErrorStrategy, spicy::Direction, spicy::Error, spicy::MatchState, spicy::Protocol, spicy::RealType, spicy::ReassemblerPolicy, spicy::Side, spicy::StreamStatistics, spicy::ZlibStream, spicy::accept_input, spicy::base64_decode, spicy::base64_encode, spicy::base64_finish, spicy::bytes_to_hexstring, spicy::crc32_add, spicy::crc32_init, spicy::current_time, spicy::decline_input, spicy::getenv, spicy::mktime, spicy::parse_address, spicy::parse_address_2, spicy::strftime, spicy::strptime, spicy::zlib_decompress, spicy::zlib_finish, spicy::zlib_init
[debug/ast-declarations] - [module] spicy -> spicy::AddressFamily, spicy::Base64Stream, spicy::BitOrder, spicy::ByteOrder, spicy::Charset, spicy::DecodeErrorStrategy, spicy::Direction, spicy::Error, spicy::MatchState, spicy::Protocol, spicy::RealType, spicy::ReassemblerPolicy, spicy::Side, spicy::StreamStatistics, spicy::ZlibStream, spicy::accept_input, spicy::base64_decode, spicy::base64_encode, spicy::base64_finish, spicy::bytes_to_hexstring, spicy::bytes_to_mac, spicy::crc32_add, spicy::crc32_init, spicy::current_time, spicy::decline_input, spicy::getenv, spicy::mktime, spicy::parse_address, spicy::parse_address_2, spicy::strftime, spicy::strptime, spicy::zlib_decompress, spicy::zlib_finish, spicy::zlib_init
[debug/ast-declarations] - [function] spicy::base64_decode -> spicy::Base64Stream
[debug/ast-declarations] - [function] spicy::base64_encode -> spicy::Base64Stream
[debug/ast-declarations] - [function] spicy::base64_finish -> spicy::Base64Stream
Expand Down
10 changes: 8 additions & 2 deletions tests/Baseline/spicy.types.unit.canonical-ids/output
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@
[debug/ast-declarations] - Parameter "S" (spicy::S)
[debug/ast-declarations] - Function "bytes_to_hexstring" (spicy::bytes_to_hexstring)
[debug/ast-declarations] - Parameter "value" (spicy::value)
[debug/ast-declarations] - Function "bytes_to_mac" (spicy::bytes_to_mac)
[debug/ast-declarations] - Parameter "value" (spicy::value_2)
[debug/ast-declarations] - Function "getenv" (spicy::getenv)
[debug/ast-declarations] - Parameter "name" (spicy::name)
[debug/ast-declarations] - Function "strftime" (spicy::strftime)
Expand Down Expand Up @@ -385,7 +387,7 @@
[debug/ast-declarations] - [function] hilti::exception_where_2 -> hilti::Exception, hilti::RecoverableFailure
[debug/ast-declarations] - [function] hilti::profiler_start -> hilti::Profiler
[debug/ast-declarations] - [function] hilti::profiler_stop -> hilti::Profiler
[debug/ast-declarations] - [module] spicy -> spicy::AddressFamily, spicy::Base64Stream, spicy::BitOrder, spicy::ByteOrder, spicy::Charset, spicy::DecodeErrorStrategy, spicy::Direction, spicy::Error, spicy::MatchState, spicy::Protocol, spicy::RealType, spicy::ReassemblerPolicy, spicy::Side, spicy::StreamStatistics, spicy::ZlibStream, spicy::accept_input, spicy::base64_decode, spicy::base64_encode, spicy::base64_finish, spicy::bytes_to_hexstring, spicy::crc32_add, spicy::crc32_init, spicy::current_time, spicy::decline_input, spicy::getenv, spicy::mktime, spicy::parse_address, spicy::parse_address_2, spicy::strftime, spicy::strptime, spicy::zlib_decompress, spicy::zlib_finish, spicy::zlib_init
[debug/ast-declarations] - [module] spicy -> spicy::AddressFamily, spicy::Base64Stream, spicy::BitOrder, spicy::ByteOrder, spicy::Charset, spicy::DecodeErrorStrategy, spicy::Direction, spicy::Error, spicy::MatchState, spicy::Protocol, spicy::RealType, spicy::ReassemblerPolicy, spicy::Side, spicy::StreamStatistics, spicy::ZlibStream, spicy::accept_input, spicy::base64_decode, spicy::base64_encode, spicy::base64_finish, spicy::bytes_to_hexstring, spicy::bytes_to_mac, spicy::crc32_add, spicy::crc32_init, spicy::current_time, spicy::decline_input, spicy::getenv, spicy::mktime, spicy::parse_address, spicy::parse_address_2, spicy::strftime, spicy::strptime, spicy::zlib_decompress, spicy::zlib_finish, spicy::zlib_init
[debug/ast-declarations] - [function] spicy::base64_decode -> spicy::Base64Stream
[debug/ast-declarations] - [function] spicy::base64_encode -> spicy::Base64Stream
[debug/ast-declarations] - [function] spicy::base64_finish -> spicy::Base64Stream
Expand Down Expand Up @@ -1061,6 +1063,8 @@
[debug/ast-declarations] - Parameter "S" (spicy::S)
[debug/ast-declarations] - Function "bytes_to_hexstring" (spicy::bytes_to_hexstring)
[debug/ast-declarations] - Parameter "value" (spicy::value)
[debug/ast-declarations] - Function "bytes_to_mac" (spicy::bytes_to_mac)
[debug/ast-declarations] - Parameter "value" (spicy::value_2)
[debug/ast-declarations] - Function "getenv" (spicy::getenv)
[debug/ast-declarations] - Parameter "name" (spicy::name)
[debug/ast-declarations] - Function "strftime" (spicy::strftime)
Expand Down Expand Up @@ -1519,6 +1523,8 @@
[debug/ast-declarations] - Parameter "S" (spicy::S)
[debug/ast-declarations] - Function "bytes_to_hexstring" (spicy::bytes_to_hexstring)
[debug/ast-declarations] - Parameter "value" (spicy::value)
[debug/ast-declarations] - Function "bytes_to_mac" (spicy::bytes_to_mac)
[debug/ast-declarations] - Parameter "value" (spicy::value_2)
[debug/ast-declarations] - Function "getenv" (spicy::getenv)
[debug/ast-declarations] - Parameter "name" (spicy::name)
[debug/ast-declarations] - Function "strftime" (spicy::strftime)
Expand Down Expand Up @@ -1556,7 +1562,7 @@
[debug/ast-declarations] - [function] hilti::exception_where_2 -> hilti::Exception, hilti::RecoverableFailure
[debug/ast-declarations] - [function] hilti::profiler_start -> hilti::Profiler
[debug/ast-declarations] - [function] hilti::profiler_stop -> hilti::Profiler
[debug/ast-declarations] - [module] spicy -> spicy::AddressFamily, spicy::Base64Stream, spicy::BitOrder, spicy::ByteOrder, spicy::Charset, spicy::DecodeErrorStrategy, spicy::Direction, spicy::Error, spicy::MatchState, spicy::Protocol, spicy::RealType, spicy::ReassemblerPolicy, spicy::Side, spicy::StreamStatistics, spicy::ZlibStream, spicy::accept_input, spicy::base64_decode, spicy::base64_encode, spicy::base64_finish, spicy::bytes_to_hexstring, spicy::crc32_add, spicy::crc32_init, spicy::current_time, spicy::decline_input, spicy::getenv, spicy::mktime, spicy::parse_address, spicy::parse_address_2, spicy::strftime, spicy::strptime, spicy::zlib_decompress, spicy::zlib_finish, spicy::zlib_init
[debug/ast-declarations] - [module] spicy -> spicy::AddressFamily, spicy::Base64Stream, spicy::BitOrder, spicy::ByteOrder, spicy::Charset, spicy::DecodeErrorStrategy, spicy::Direction, spicy::Error, spicy::MatchState, spicy::Protocol, spicy::RealType, spicy::ReassemblerPolicy, spicy::Side, spicy::StreamStatistics, spicy::ZlibStream, spicy::accept_input, spicy::base64_decode, spicy::base64_encode, spicy::base64_finish, spicy::bytes_to_hexstring, spicy::bytes_to_mac, spicy::crc32_add, spicy::crc32_init, spicy::current_time, spicy::decline_input, spicy::getenv, spicy::mktime, spicy::parse_address, spicy::parse_address_2, spicy::strftime, spicy::strptime, spicy::zlib_decompress, spicy::zlib_finish, spicy::zlib_init
[debug/ast-declarations] - [function] spicy::base64_decode -> spicy::Base64Stream
[debug/ast-declarations] - [function] spicy::base64_encode -> spicy::Base64Stream
[debug/ast-declarations] - [function] spicy::base64_finish -> spicy::Base64Stream
Expand Down
9 changes: 9 additions & 0 deletions tests/spicy/lib/bytes_to_mac.spicy
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# @TEST-EXEC: ${SPICYC} -j %INPUT

module Test;

import spicy;

assert spicy::bytes_to_mac(b"\x01\x23\xff") == "01:23:FF";
assert spicy::bytes_to_mac(b"\x01") == "01";
assert spicy::bytes_to_mac(b"") == "";

0 comments on commit a49287e

Please sign in to comment.