Skip to content

Commit cf60701

Browse files
authored
Keep dynamic anchor label hashes under 2^53 - 1 (#677)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent c018dcb commit cf60701

1 file changed

Lines changed: 7 additions & 3 deletions

File tree

src/evaluator/include/sourcemeta/blaze/evaluator.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,16 +195,20 @@ class SOURCEMETA_BLAZE_EVALUATOR_EXPORT Evaluator {
195195
static inline const sourcemeta::core::JSON empty_string{""};
196196
// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
197197

198+
// Compute a hash that fits within the IEEE 754 double-precision safe
199+
// integer range (2^53 - 1), ensuring the serialized template labels
200+
// are usable from JavaScript and other languages whose numbers are doubles
198201
[[nodiscard]] static auto hash(const std::size_t resource,
199202
const std::string_view fragment) noexcept
200203
-> std::size_t {
201-
std::size_t result{14695981039346656037ULL};
204+
constexpr std::size_t mask{(1ULL << 53) - 1};
205+
std::size_t result{14695981039346656037ULL & mask};
202206
for (const auto byte : fragment) {
203207
result ^= static_cast<std::size_t>(static_cast<unsigned char>(byte));
204-
result *= 1099511628211ULL;
208+
result = (result * 1099511628211ULL) & mask;
205209
}
206210

207-
return resource + result;
211+
return (resource + result) & mask;
208212
}
209213

210214
auto evaluate(const sourcemeta::core::JSON *target) -> void {

0 commit comments

Comments
 (0)