Fix _hashlib

This commit is contained in:
Jeong, YunWon committed 2026-02-14 21:40:04 +09:00
1 parent 1f290dccfe
commit 12db02eaf0
11 files changed
+362 -67

No files matched your search

Generated
+2
View File
@@ -3226,6 +3226,7 @@ dependencies = [
"foreign-types-shared",
"gethostname",
"hex",
"hmac",
"indexmap",
"itertools 0.14.0",
"libc",
@@ -3250,6 +3251,7 @@ dependencies = [
"page_size",
"parking_lot",
"paste",
"pbkdf2",
"pem-rfc7468 1.0.0",
"phf 0.13.1",
"pkcs8",
+2 -2
View File
@@ -3717,7 +3717,7 @@ impl Compiler {
// Compile kwdefaults and build dict
for (arg, default) in &kw_with_defaults {
self.emit_load_const(ConstantData::Str {
value: arg.name.as_str().into(),
value: self.mangle(arg.name.as_str()).into_owned().into(),
});
self.compile_expression(default)?;
}
@@ -6983,7 +6983,7 @@ impl Compiler {
let default_kw_count = kw_with_defaults.len();
for (arg, default) in &kw_with_defaults {
self.emit_load_const(ConstantData::Str {
value: arg.name.as_str().into(),
value: self.mangle(arg.name.as_str()).into_owned().into(),
});
self.compile_expression(default)?;
}
+3 -1
View File
@@ -61,12 +61,14 @@ rand_core = { workspace = true }
mt19937 = "3.1"
# Crypto:
digest = "0.10.3"
digest = "0.10.7"
md-5 = "0.10.1"
sha-1 = "0.10.0"
sha2 = "0.10.2"
sha3 = "0.10.1"
blake2 = "0.10.4"
hmac = "0.12"
pbkdf2 = { version = "0.12", features = ["hmac"] }
## unicode stuff
unicode_names2 = { workspace = true }
+2 -2
View File
@@ -9,11 +9,11 @@ mod _blake2 {
#[pyfunction]
fn blake2b(args: BlakeHashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_blake2b(args).into_pyobject(vm))
Ok(local_blake2b(args, vm)?.into_pyobject(vm))
}
#[pyfunction]
fn blake2s(args: BlakeHashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_blake2s(args).into_pyobject(vm))
Ok(local_blake2s(args, vm)?.into_pyobject(vm))
}
}
+340 -49
View File
@@ -1,4 +1,7 @@
// spell-checker:ignore usedforsecurity HASHXOF
// spell-checker:ignore usedforsecurity HASHXOF hashopenssl dklen
// NOTE: Function names like `openssl_md5` match CPython's `_hashopenssl.c` interface
// for compatibility, but the implementation uses pure Rust crates (md5, sha2, etc.),
// not OpenSSL.
pub(crate) use _hashlib::module_def;
@@ -7,7 +10,9 @@ pub mod _hashlib {
use crate::common::lock::PyRwLock;
use crate::vm::{
Py, PyObjectRef, PyPayload, PyResult, VirtualMachine,
builtins::{PyBytes, PyStrRef, PyTypeRef, PyValueError},
builtins::{
PyBaseExceptionRef, PyBytes, PyFrozenSet, PyStr, PyStrRef, PyTypeRef, PyValueError,
},
class::StaticType,
convert::ToPyObject,
function::{ArgBytesLike, ArgStrOrBytesLike, FuncArgs, OptionalArg},
@@ -17,17 +22,59 @@ pub mod _hashlib {
use digest::{DynDigest, core_api::BlockSizeUser};
use digest::{ExtendableOutput, Update};
use dyn_clone::{DynClone, clone_trait_object};
use hmac::Mac;
use md5::Md5;
use sha1::Sha1;
use sha2::{Sha224, Sha256, Sha384, Sha512};
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256};
const HASH_ALGORITHMS: &[&str] = &[
"md5",
"sha1",
"sha224",
"sha256",
"sha384",
"sha512",
"sha3_224",
"sha3_256",
"sha3_384",
"sha3_512",
"shake_128",
"shake_256",
"blake2b",
"blake2s",
];
#[pyattr]
const _GIL_MINSIZE: usize = 2048;
#[pyattr]
#[pyexception(name = "UnsupportedDigestmodError", base = PyValueError, impl)]
#[derive(Debug)]
#[repr(transparent)]
pub struct UnsupportedDigestmodError(PyValueError);
#[pyattr]
fn openssl_md_meth_names(vm: &VirtualMachine) -> PyObjectRef {
PyFrozenSet::from_iter(
vm,
HASH_ALGORITHMS.iter().map(|n| vm.ctx.new_str(*n).into()),
)
.expect("failed to create openssl_md_meth_names frozenset")
.into_ref(&vm.ctx)
.into()
}
#[pyattr]
fn _constructors(vm: &VirtualMachine) -> PyObjectRef {
let dict = vm.ctx.new_dict();
for name in HASH_ALGORITHMS {
let s = vm.ctx.new_str(*name);
dict.set_item(&*s, s.clone().into(), vm).unwrap();
}
dict.into()
}
#[derive(FromArgs, Debug)]
#[allow(unused)]
struct NewHashArgs {
@@ -37,15 +84,19 @@ pub mod _hashlib {
data: OptionalArg<ArgBytesLike>,
#[pyarg(named, default = true)]
usedforsecurity: bool,
#[pyarg(named, optional)]
string: OptionalArg<ArgBytesLike>,
}
#[derive(FromArgs)]
#[allow(unused)]
pub struct BlakeHashArgs {
#[pyarg(positional, optional)]
#[pyarg(any, optional)]
pub data: OptionalArg<ArgBytesLike>,
#[pyarg(named, default = true)]
usedforsecurity: bool,
#[pyarg(named, optional)]
pub string: OptionalArg<ArgBytesLike>,
}
impl From<NewHashArgs> for BlakeHashArgs {
@@ -53,6 +104,7 @@ pub mod _hashlib {
Self {
data: args.data,
usedforsecurity: args.usedforsecurity,
string: args.string,
}
}
}
@@ -61,16 +113,19 @@ pub mod _hashlib {
#[allow(unused)]
pub struct HashArgs {
#[pyarg(any, optional)]
pub string: OptionalArg<ArgBytesLike>,
pub data: OptionalArg<ArgBytesLike>,
#[pyarg(named, default = true)]
usedforsecurity: bool,
#[pyarg(named, optional)]
pub string: OptionalArg<ArgBytesLike>,
}
impl From<NewHashArgs> for HashArgs {
fn from(args: NewHashArgs) -> Self {
Self {
string: args.data,
data: args.data,
usedforsecurity: args.usedforsecurity,
string: args.string,
}
}
}
@@ -118,6 +173,91 @@ pub mod _hashlib {
}
}
#[derive(FromArgs)]
#[allow(unused)]
struct HmacDigestArgs {
#[pyarg(positional)]
key: ArgBytesLike,
#[pyarg(positional)]
msg: ArgBytesLike,
#[pyarg(positional)]
digest: PyObjectRef,
}
#[derive(FromArgs)]
#[allow(unused)]
struct Pbkdf2HmacArgs {
#[pyarg(any)]
hash_name: PyStrRef,
#[pyarg(any)]
password: ArgBytesLike,
#[pyarg(any)]
salt: ArgBytesLike,
#[pyarg(any)]
iterations: i64,
#[pyarg(any, optional)]
dklen: OptionalArg<PyObjectRef>,
}
fn resolve_data(
data: OptionalArg<ArgBytesLike>,
string: OptionalArg<ArgBytesLike>,
vm: &VirtualMachine,
) -> PyResult<OptionalArg<ArgBytesLike>> {
match (data.into_option(), string.into_option()) {
(Some(d), None) => Ok(OptionalArg::Present(d)),
(None, Some(s)) => Ok(OptionalArg::Present(s)),
(None, None) => Ok(OptionalArg::Missing),
(Some(_), Some(_)) => Err(vm.new_type_error(
"'data' and 'string' are mutually exclusive \
and support for 'string' keyword parameter \
is slated for removal in a future version."
.to_owned(),
)),
}
}
fn resolve_digestmod(digestmod: &PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
if let Some(name) = digestmod.downcast_ref::<PyStr>() {
return Ok(name.as_str().to_lowercase());
}
if let Ok(name_obj) = digestmod.get_attr("__name__", vm)
&& let Some(name) = name_obj.downcast_ref::<PyStr>()
&& let Some(algo) = name.as_str().strip_prefix("openssl_")
{
return Ok(algo.to_owned());
}
Err(vm.new_exception_msg(
UnsupportedDigestmodError::static_type().to_owned(),
"unsupported digestmod".to_owned(),
))
}
fn hash_digest_size(name: &str) -> Option<usize> {
match name {
"md5" => Some(16),
"sha1" => Some(20),
"sha224" => Some(28),
"sha256" => Some(32),
"sha384" => Some(48),
"sha512" => Some(64),
"sha3_224" => Some(28),
"sha3_256" => Some(32),
"sha3_384" => Some(48),
"sha3_512" => Some(64),
"blake2b" => Some(64),
"blake2s" => Some(32),
_ => None,
}
}
fn unsupported_hash(name: &str, vm: &VirtualMachine) -> PyBaseExceptionRef {
vm.new_exception_msg(
UnsupportedDigestmodError::static_type().to_owned(),
format!("unsupported hash type {name}"),
)
}
#[pyattr]
#[pyclass(module = "_hashlib", name = "HASH")]
#[derive(PyPayload)]
@@ -309,93 +449,163 @@ pub mod _hashlib {
#[pyfunction(name = "new")]
fn hashlib_new(args: NewHashArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let data = resolve_data(args.data, args.string, vm)?;
match args.name.as_str().to_lowercase().as_str() {
"md5" => Ok(local_md5(args.into()).into_pyobject(vm)),
"sha1" => Ok(local_sha1(args.into()).into_pyobject(vm)),
"sha224" => Ok(local_sha224(args.into()).into_pyobject(vm)),
"sha256" => Ok(local_sha256(args.into()).into_pyobject(vm)),
"sha384" => Ok(local_sha384(args.into()).into_pyobject(vm)),
"sha512" => Ok(local_sha512(args.into()).into_pyobject(vm)),
"sha3_224" => Ok(local_sha3_224(args.into()).into_pyobject(vm)),
"sha3_256" => Ok(local_sha3_256(args.into()).into_pyobject(vm)),
"sha3_384" => Ok(local_sha3_384(args.into()).into_pyobject(vm)),
"sha3_512" => Ok(local_sha3_512(args.into()).into_pyobject(vm)),
"shake_128" => Ok(local_shake_128(args.into()).into_pyobject(vm)),
"shake_256" => Ok(local_shake_256(args.into()).into_pyobject(vm)),
"blake2b" => Ok(local_blake2b(args.into()).into_pyobject(vm)),
"blake2s" => Ok(local_blake2s(args.into()).into_pyobject(vm)),
"md5" => Ok(PyHasher::new("md5", HashWrapper::new::<Md5>(data)).into_pyobject(vm)),
"sha1" => Ok(PyHasher::new("sha1", HashWrapper::new::<Sha1>(data)).into_pyobject(vm)),
"sha224" => {
Ok(PyHasher::new("sha224", HashWrapper::new::<Sha224>(data)).into_pyobject(vm))
}
"sha256" => {
Ok(PyHasher::new("sha256", HashWrapper::new::<Sha256>(data)).into_pyobject(vm))
}
"sha384" => {
Ok(PyHasher::new("sha384", HashWrapper::new::<Sha384>(data)).into_pyobject(vm))
}
"sha512" => {
Ok(PyHasher::new("sha512", HashWrapper::new::<Sha512>(data)).into_pyobject(vm))
}
"sha3_224" => {
Ok(PyHasher::new("sha3_224", HashWrapper::new::<Sha3_224>(data)).into_pyobject(vm))
}
"sha3_256" => {
Ok(PyHasher::new("sha3_256", HashWrapper::new::<Sha3_256>(data)).into_pyobject(vm))
}
"sha3_384" => {
Ok(PyHasher::new("sha3_384", HashWrapper::new::<Sha3_384>(data)).into_pyobject(vm))
}
"sha3_512" => {
Ok(PyHasher::new("sha3_512", HashWrapper::new::<Sha3_512>(data)).into_pyobject(vm))
}
"shake_128" => Ok(
PyHasherXof::new("shake_128", HashXofWrapper::new_shake_128(data))
.into_pyobject(vm),
),
"shake_256" => Ok(
PyHasherXof::new("shake_256", HashXofWrapper::new_shake_256(data))
.into_pyobject(vm),
),
"blake2b" => Ok(
PyHasher::new("blake2b", HashWrapper::new::<Blake2b512>(data)).into_pyobject(vm),
),
"blake2s" => Ok(
PyHasher::new("blake2s", HashWrapper::new::<Blake2s256>(data)).into_pyobject(vm),
),
other => Err(vm.new_value_error(format!("Unknown hashing algorithm: {other}"))),
}
}
#[pyfunction(name = "openssl_md5")]
pub fn local_md5(args: HashArgs) -> PyHasher {
PyHasher::new("md5", HashWrapper::new::<Md5>(args.string))
pub fn local_md5(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new("md5", HashWrapper::new::<Md5>(data)))
}
#[pyfunction(name = "openssl_sha1")]
pub fn local_sha1(args: HashArgs) -> PyHasher {
PyHasher::new("sha1", HashWrapper::new::<Sha1>(args.string))
pub fn local_sha1(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new("sha1", HashWrapper::new::<Sha1>(data)))
}
#[pyfunction(name = "openssl_sha224")]
pub fn local_sha224(args: HashArgs) -> PyHasher {
PyHasher::new("sha224", HashWrapper::new::<Sha224>(args.string))
pub fn local_sha224(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new("sha224", HashWrapper::new::<Sha224>(data)))
}
#[pyfunction(name = "openssl_sha256")]
pub fn local_sha256(args: HashArgs) -> PyHasher {
PyHasher::new("sha256", HashWrapper::new::<Sha256>(args.string))
pub fn local_sha256(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new("sha256", HashWrapper::new::<Sha256>(data)))
}
#[pyfunction(name = "openssl_sha384")]
pub fn local_sha384(args: HashArgs) -> PyHasher {
PyHasher::new("sha384", HashWrapper::new::<Sha384>(args.string))
pub fn local_sha384(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new("sha384", HashWrapper::new::<Sha384>(data)))
}
#[pyfunction(name = "openssl_sha512")]
pub fn local_sha512(args: HashArgs) -> PyHasher {
PyHasher::new("sha512", HashWrapper::new::<Sha512>(args.string))
pub fn local_sha512(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new("sha512", HashWrapper::new::<Sha512>(data)))
}
#[pyfunction(name = "openssl_sha3_224")]
pub fn local_sha3_224(args: HashArgs) -> PyHasher {
PyHasher::new("sha3_224", HashWrapper::new::<Sha3_224>(args.string))
pub fn local_sha3_224(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new(
"sha3_224",
HashWrapper::new::<Sha3_224>(data),
))
}
#[pyfunction(name = "openssl_sha3_256")]
pub fn local_sha3_256(args: HashArgs) -> PyHasher {
PyHasher::new("sha3_256", HashWrapper::new::<Sha3_256>(args.string))
pub fn local_sha3_256(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new(
"sha3_256",
HashWrapper::new::<Sha3_256>(data),
))
}
#[pyfunction(name = "openssl_sha3_384")]
pub fn local_sha3_384(args: HashArgs) -> PyHasher {
PyHasher::new("sha3_384", HashWrapper::new::<Sha3_384>(args.string))
pub fn local_sha3_384(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new(
"sha3_384",
HashWrapper::new::<Sha3_384>(data),
))
}
#[pyfunction(name = "openssl_sha3_512")]
pub fn local_sha3_512(args: HashArgs) -> PyHasher {
PyHasher::new("sha3_512", HashWrapper::new::<Sha3_512>(args.string))
pub fn local_sha3_512(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new(
"sha3_512",
HashWrapper::new::<Sha3_512>(data),
))
}
#[pyfunction(name = "openssl_shake_128")]
pub fn local_shake_128(args: HashArgs) -> PyHasherXof {
PyHasherXof::new("shake_128", HashXofWrapper::new_shake_128(args.string))
pub fn local_shake_128(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasherXof> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasherXof::new(
"shake_128",
HashXofWrapper::new_shake_128(data),
))
}
#[pyfunction(name = "openssl_shake_256")]
pub fn local_shake_256(args: HashArgs) -> PyHasherXof {
PyHasherXof::new("shake_256", HashXofWrapper::new_shake_256(args.string))
pub fn local_shake_256(args: HashArgs, vm: &VirtualMachine) -> PyResult<PyHasherXof> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasherXof::new(
"shake_256",
HashXofWrapper::new_shake_256(data),
))
}
#[pyfunction(name = "openssl_blake2b")]
pub fn local_blake2b(args: BlakeHashArgs) -> PyHasher {
PyHasher::new("blake2b", HashWrapper::new::<Blake2b512>(args.data))
pub fn local_blake2b(args: BlakeHashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new(
"blake2b",
HashWrapper::new::<Blake2b512>(data),
))
}
#[pyfunction(name = "openssl_blake2s")]
pub fn local_blake2s(args: BlakeHashArgs) -> PyHasher {
PyHasher::new("blake2s", HashWrapper::new::<Blake2s256>(args.data))
pub fn local_blake2s(args: BlakeHashArgs, vm: &VirtualMachine) -> PyResult<PyHasher> {
let data = resolve_data(args.data, args.string, vm)?;
Ok(PyHasher::new(
"blake2s",
HashWrapper::new::<Blake2s256>(data),
))
}
#[pyfunction]
fn get_fips_mode() -> i32 {
0
}
#[pyfunction]
@@ -434,7 +644,6 @@ pub mod _hashlib {
#[pyfunction]
fn hmac_new(args: NewHMACHashArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
// Raise UnsupportedDigestmodError so Python's hmac.py falls back to pure-Python implementation
let _ = args;
Err(vm.new_exception_msg(
UnsupportedDigestmodError::static_type().to_owned(),
@@ -442,12 +651,94 @@ pub mod _hashlib {
))
}
#[pyfunction]
fn hmac_digest(args: HmacDigestArgs, vm: &VirtualMachine) -> PyResult<PyBytes> {
let name = resolve_digestmod(&args.digest, vm)?;
let key_buf = args.key.borrow_buf();
let msg_buf = args.msg.borrow_buf();
macro_rules! do_hmac {
($hash_ty:ty) => {{
let mut mac = <hmac::Hmac<$hash_ty> as Mac>::new_from_slice(&key_buf)
.map_err(|_| vm.new_value_error("invalid key length".to_owned()))?;
Mac::update(&mut mac, &msg_buf);
Ok(mac.finalize().into_bytes().to_vec().into())
}};
}
match name.as_str() {
"md5" => do_hmac!(Md5),
"sha1" => do_hmac!(Sha1),
"sha224" => do_hmac!(Sha224),
"sha256" => do_hmac!(Sha256),
"sha384" => do_hmac!(Sha384),
"sha512" => do_hmac!(Sha512),
"sha3_224" => do_hmac!(Sha3_224),
"sha3_256" => do_hmac!(Sha3_256),
"sha3_384" => do_hmac!(Sha3_384),
"sha3_512" => do_hmac!(Sha3_512),
_ => Err(unsupported_hash(&name, vm)),
}
}
#[pyfunction]
fn pbkdf2_hmac(args: Pbkdf2HmacArgs, vm: &VirtualMachine) -> PyResult<PyBytes> {
let name = args.hash_name.as_str().to_lowercase();
if args.iterations < 1 {
return Err(vm.new_value_error("iteration value must be greater than 0.".to_owned()));
}
let rounds = u32::try_from(args.iterations)
.map_err(|_| vm.new_overflow_error("iteration value is too great.".to_owned()))?;
let dklen: usize = match args.dklen.into_option() {
Some(obj) if vm.is_none(&obj) => {
hash_digest_size(&name).ok_or_else(|| unsupported_hash(&name, vm))?
}
Some(obj) => {
let len: i64 = obj.try_into_value(vm)?;
if len < 1 {
return Err(vm.new_value_error("key length must be greater than 0.".to_owned()));
}
usize::try_from(len).map_err(|_| {
vm.new_overflow_error("key length is too great.".to_owned())
})?
}
None => hash_digest_size(&name).ok_or_else(|| unsupported_hash(&name, vm))?,
};
let password_buf = args.password.borrow_buf();
let salt_buf = args.salt.borrow_buf();
let mut dk = vec![0u8; dklen];
macro_rules! do_pbkdf2 {
($hash_ty:ty) => {{
pbkdf2::pbkdf2_hmac::<$hash_ty>(&password_buf, &salt_buf, rounds, &mut dk);
Ok(dk.into())
}};
}
match name.as_str() {
"md5" => do_pbkdf2!(Md5),
"sha1" => do_pbkdf2!(Sha1),
"sha224" => do_pbkdf2!(Sha224),
"sha256" => do_pbkdf2!(Sha256),
"sha384" => do_pbkdf2!(Sha384),
"sha512" => do_pbkdf2!(Sha512),
"sha3_224" => do_pbkdf2!(Sha3_224),
"sha3_256" => do_pbkdf2!(Sha3_256),
"sha3_384" => do_pbkdf2!(Sha3_384),
"sha3_512" => do_pbkdf2!(Sha3_512),
_ => Err(unsupported_hash(&name, vm)),
}
}
pub trait ThreadSafeDynDigest: DynClone + DynDigest + Sync + Send {}
impl<T> ThreadSafeDynDigest for T where T: DynClone + DynDigest + Sync + Send {}
clone_trait_object!(ThreadSafeDynDigest);
/// Generic wrapper patching around the hashing libraries.
#[derive(Clone)]
pub struct HashWrapper {
block_size: usize,
+1 -1
View File
@@ -7,6 +7,6 @@ mod _md5 {
#[pyfunction]
fn md5(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_md5(args).into_pyobject(vm))
Ok(local_md5(args, vm)?.into_pyobject(vm))
}
}
+1 -1
View File
@@ -7,6 +7,6 @@ mod _sha1 {
#[pyfunction]
fn sha1(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_sha1(args).into_pyobject(vm))
Ok(local_sha1(args, vm)?.into_pyobject(vm))
}
}
+2 -2
View File
@@ -5,12 +5,12 @@ mod _sha256 {
#[pyfunction]
fn sha224(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_sha224(args).into_pyobject(vm))
Ok(local_sha224(args, vm)?.into_pyobject(vm))
}
#[pyfunction]
fn sha256(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_sha256(args).into_pyobject(vm))
Ok(local_sha256(args, vm)?.into_pyobject(vm))
}
pub(crate) fn module_exec(vm: &VirtualMachine, module: &Py<PyModule>) -> PyResult<()> {
+6 -6
View File
@@ -10,31 +10,31 @@ mod _sha3 {
#[pyfunction]
fn sha3_224(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_sha3_224(args).into_pyobject(vm))
Ok(local_sha3_224(args, vm)?.into_pyobject(vm))
}
#[pyfunction]
fn sha3_256(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_sha3_256(args).into_pyobject(vm))
Ok(local_sha3_256(args, vm)?.into_pyobject(vm))
}
#[pyfunction]
fn sha3_384(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_sha3_384(args).into_pyobject(vm))
Ok(local_sha3_384(args, vm)?.into_pyobject(vm))
}
#[pyfunction]
fn sha3_512(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_sha3_512(args).into_pyobject(vm))
Ok(local_sha3_512(args, vm)?.into_pyobject(vm))
}
#[pyfunction]
fn shake_128(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_shake_128(args).into_pyobject(vm))
Ok(local_shake_128(args, vm)?.into_pyobject(vm))
}
#[pyfunction]
fn shake_256(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_shake_256(args).into_pyobject(vm))
Ok(local_shake_256(args, vm)?.into_pyobject(vm))
}
}
+2 -2
View File
@@ -5,12 +5,12 @@ mod _sha512 {
#[pyfunction]
fn sha384(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_sha384(args).into_pyobject(vm))
Ok(local_sha384(args, vm)?.into_pyobject(vm))
}
#[pyfunction]
fn sha512(args: HashArgs, vm: &VirtualMachine) -> PyResult {
Ok(local_sha512(args).into_pyobject(vm))
Ok(local_sha512(args, vm)?.into_pyobject(vm))
}
pub(crate) fn module_exec(vm: &VirtualMachine, module: &Py<PyModule>) -> PyResult<()> {
+1 -1
View File
@@ -397,7 +397,7 @@ impl VirtualMachine {
)?;
let mode = if write { "w" } else { "r" };
stdio.set_attr("mode", self.ctx.new_str(mode), self)?;
Ok(stdio)
Ok::<_, self::PyBaseExceptionRef>(stdio)
};
// Sandbox stdio: lightweight wrapper using Rust's std::io directly