-
Notifications
You must be signed in to change notification settings - Fork 0
Add Byte Array specialization #134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
9ec0d0b
Add byte array specialization and processing
Waguramu 1240d9d
Add byte array
Waguramu 5d1bf1e
Remove extraneous output
Waguramu 988514e
Remove byteArrayData_ column
Waguramu b5e58d9
Introduce a generic ADL-based Model::resolve function.
josephbirkner 6b01ea8
Address PR comments.
josephbirkner 74b02fc
Add a Bytes value type which is returned by ValueType4CType<ByteArray…
Waguramu 0d13c00
Merge remote-tracking branch 'origin/improvement/generic-resolve' int…
josephbirkner bd975b3
Fix mp_key usage.
josephbirkner 2484898
Do not use k* prefixes. Use fmt::format instead of custom hex encodin…
Waguramu f59f6f7
Allow ByteArray conversion for strings, bool and int
Waguramu 9f4b9a5
Fix duplication
Waguramu 85304dc
Fix tests
Waguramu eb25799
Fix tests
Waguramu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| // Copyright (c) Navigation Data Standard e.V. - See "LICENSE" file. | ||
| #pragma once | ||
|
|
||
| #include <cstdint> | ||
| #include <cstring> | ||
| #include <iterator> | ||
| #include <optional> | ||
| #include <string> | ||
| #include <string_view> | ||
| #include <utility> | ||
|
|
||
| #include <fmt/format.h> | ||
|
|
||
| namespace simfil | ||
| { | ||
|
|
||
| struct ByteArray | ||
| { | ||
| std::string bytes; | ||
|
|
||
| ByteArray() = default; | ||
|
|
||
| explicit ByteArray(const char* data) | ||
| : bytes(data) | ||
| {} | ||
|
|
||
| explicit ByteArray(std::string_view data) | ||
| : bytes(data) | ||
| {} | ||
|
|
||
| explicit ByteArray(std::string data) | ||
| : bytes(std::move(data)) | ||
| {} | ||
|
|
||
| auto operator==(const ByteArray&) const -> bool = default; | ||
|
|
||
| [[nodiscard]] static std::optional<ByteArray> fromHex(std::string_view hex) | ||
| { | ||
| if (hex.size() % 2 != 0) | ||
| return std::nullopt; | ||
|
|
||
| std::string decoded; | ||
| decoded.reserve(hex.size() / 2); | ||
| for (size_t i = 0; i < hex.size(); i += 2) { | ||
| const auto upper = decodeHexNibble(hex[i]); | ||
| const auto lower = decodeHexNibble(hex[i + 1]); | ||
| if (upper < 0 || lower < 0) | ||
| return std::nullopt; | ||
| decoded.push_back(static_cast<char>((upper << 4) | lower)); | ||
| } | ||
|
|
||
| return ByteArray{std::move(decoded)}; | ||
| } | ||
|
|
||
| [[nodiscard]] std::optional<int64_t> decodeBigEndianI64() const | ||
| { | ||
| if (bytes.size() > 8) { | ||
| for (size_t i = 8; i < bytes.size(); ++i) { | ||
| if (static_cast<unsigned char>(bytes[i]) != 0) | ||
| return std::nullopt; | ||
| } | ||
| } | ||
|
|
||
| const size_t count = bytes.size() <= 8 ? bytes.size() : 8; | ||
| uint64_t value = 0; | ||
| for (size_t i = 0; i < count; ++i) { | ||
| value = (value << 8) | static_cast<unsigned char>(bytes[i]); | ||
| } | ||
|
|
||
| int64_t signedValue = 0; | ||
| std::memcpy(&signedValue, &value, sizeof(signedValue)); | ||
| return signedValue; | ||
| } | ||
|
|
||
| [[nodiscard]] std::string toHex(bool uppercase = true) const | ||
| { | ||
| std::string out; | ||
| out.reserve(bytes.size() * 2); | ||
|
|
||
| if (uppercase) { | ||
| for (unsigned char byte : bytes) | ||
| fmt::format_to(std::back_inserter(out), FMT_STRING("{:02X}"), byte); | ||
| } else { | ||
| for (unsigned char byte : bytes) | ||
| fmt::format_to(std::back_inserter(out), FMT_STRING("{:02x}"), byte); | ||
| } | ||
|
|
||
| return out; | ||
| } | ||
|
|
||
| [[nodiscard]] std::string toLiteral() const | ||
| { | ||
| std::string out; | ||
| out.reserve(bytes.size() + 3); | ||
| out += "b\""; | ||
|
|
||
| for (unsigned char byte : bytes) { | ||
| switch (byte) { | ||
| case '\\': out += "\\\\"; break; | ||
| case '"': out += "\\\""; break; | ||
| case '\n': out += "\\n"; break; | ||
| case '\r': out += "\\r"; break; | ||
| case '\t': out += "\\t"; break; | ||
| default: | ||
| if (byte < 0x20 || byte >= 0x7f) | ||
| fmt::format_to(std::back_inserter(out), FMT_STRING("\\x{:02X}"), byte); | ||
| else | ||
| out.push_back(static_cast<char>(byte)); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| out.push_back('"'); | ||
| return out; | ||
| } | ||
|
|
||
| [[nodiscard]] static auto decodeHexNibble(char c) -> int | ||
| { | ||
| if ('0' <= c && c <= '9') | ||
| return c - '0'; | ||
| if ('a' <= c && c <= 'f') | ||
| return c - 'a' + 10; | ||
| if ('A' <= c && c <= 'F') | ||
| return c - 'A' + 10; | ||
| return -1; | ||
| } | ||
| }; | ||
|
|
||
| } // namespace simfil | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Big-endian decode logic truncates wrong bytes for overflow
High Severity
The
decodeBigEndianI64function incorrectly handles byte arrays longer than 8 bytes. It checks if trailing bytes (indices 8+) are zero and then uses the leading 8 bytes. In big-endian, trailing bytes are the least significant, so this logic rejects valid values that fit in 64 bits (like 256 in a 10-byte array) while accepting values that overflow (like 2^72 truncated to its high bytes). The check for overflow needs to verify the leading excess bytes are zero (or proper sign extension), not the trailing ones.