Skip to content

Commit 7b36c9e

Browse files
Copilotyouknowonegithub-actions[bot]
authored
Handle oversized __hash__ results without panicking (#6561)
* Initial plan * Fix hash wrapper overflow handling Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com> * Auto-format: cargo fmt --all * Adjust __hash__ wrapper conversion Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com> * Auto-format: cargo fmt --all --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 75daf6f commit 7b36c9e

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

crates/vm/src/types/slot.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
66
builtins::{PyInt, PyStr, PyStrInterned, PyStrRef, PyType, PyTypeRef},
77
bytecode::ComparisonOperator,
8-
common::hash::PyHash,
8+
common::hash::{PyHash, fix_sentinel, hash_bigint},
99
convert::ToPyObject,
1010
function::{
1111
Either, FromArgs, FuncArgs, OptionalArg, PyComparisonValue, PyMethodDef, PySetterValue,
@@ -18,7 +18,6 @@ use crate::{
1818
vm::Context,
1919
};
2020
use crossbeam_utils::atomic::AtomicCell;
21-
use malachite_bigint::BigInt;
2221
use num_traits::{Signed, ToPrimitive};
2322
use std::{any::Any, any::TypeId, borrow::Borrow, cmp::Ordering, ops::Deref};
2423

@@ -412,9 +411,10 @@ fn hash_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<PyHash> {
412411
.downcast_ref::<PyInt>()
413412
.ok_or_else(|| vm.new_type_error("__hash__ method should return an integer"))?;
414413
let big_int = py_int.as_bigint();
415-
let hash: PyHash = big_int
414+
let hash = big_int
416415
.to_i64()
417-
.unwrap_or_else(|| (big_int % BigInt::from(u64::MAX)).to_i64().unwrap());
416+
.map(fix_sentinel)
417+
.unwrap_or_else(|| hash_bigint(big_int));
418418
Ok(hash)
419419
}
420420

extra_tests/snippets/builtin_hash.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ class A:
1212
assert type(hash(1.1)) is int
1313
assert type(hash("")) is int
1414

15+
16+
class Evil:
17+
def __hash__(self):
18+
return 1 << 63
19+
20+
21+
assert hash(Evil()) == 4
22+
1523
with assert_raises(TypeError):
1624
hash({})
1725

0 commit comments

Comments
 (0)