Skip to content

Commit 5d9b4e4

Browse files
committed
Remove UB from scan_result_base::rel
1 parent b86121d commit 5d9b4e4

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

include/libhat/scanner.hpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ LIBHAT_EXPORT namespace hat {
2626
explicit(false) constexpr scan_result_base(std::nullptr_t) noexcept : result(nullptr) {}
2727
explicit(false) constexpr scan_result_base(const underlying_type result) noexcept : result(result) {}
2828

29-
/// Reads an integer of the specified type located at an offset from the signature result
29+
/// Reads an integer of the specified type located at an offset from the signature result. If there is no
30+
/// result, the behavior is undefined.
3031
template<std::integral Int>
3132
[[nodiscard]] constexpr Int read(const size_t offset) const noexcept {
3233
if LIBHAT_IF_CONSTEVAL {
@@ -41,14 +42,15 @@ LIBHAT_EXPORT namespace hat {
4142
}
4243
}
4344

44-
/// Reads an integer of the specified type which represents an index into an array with the given element type
45+
/// Reads an integer of the specified type, which represents an index into an array with the given element type.
46+
/// If there is no result, the behavior is undefined.
4547
template<std::integral Int, typename ArrayType>
4648
[[nodiscard]] constexpr size_t index(const size_t offset) const noexcept {
4749
return static_cast<size_t>(read<Int>(offset)) / sizeof(ArrayType);
4850
}
4951

50-
/// Resolve the relative address located at an offset from the signature result. The behavior is undefined if
51-
/// there is no result. The "offset" parameter is the number of bytes after the result's match that the relative
52+
/// Resolve the relative address located at an offset from the signature result. If there is no result, nullptr
53+
/// is returned instead. The "offset" parameter is the number of bytes after the result's match that the relative
5254
/// address is located. For example:
5355
///
5456
/// | result matches here
@@ -71,6 +73,9 @@ LIBHAT_EXPORT namespace hat {
7173
/// address in this case is 0x12353BE + 0x7 = 0x12353C5. Simply using rel(2) would yield an incorrect result of
7274
/// 0x12353C4. In this case, rel(2, 1) would yield the expected 0x12353C5.
7375
[[nodiscard]] constexpr underlying_type rel(size_t offset, size_t remaining = 0) const noexcept {
76+
if (!this->has_result()) LIBHAT_UNLIKELY {
77+
return nullptr;
78+
}
7479
using rel32_t = int32_t;
7580
return this->result + this->read<rel32_t>(offset) + offset + sizeof(rel32_t) + remaining;
7681
}

0 commit comments

Comments
 (0)