gh-132987: Support __index__() in hashlib.scrypt() (GH-133100)
Even if such signature is not supported by PyArg_ParseTupleAndKeywords(), Argument Clinic supports it with inlined converters.
This commit is contained in:
parent
07edc0d2b2
commit
d6da6803a1
@ -1388,19 +1388,15 @@ end:
|
||||
|
||||
#ifdef PY_OPENSSL_HAS_SCRYPT
|
||||
|
||||
/* XXX: Parameters salt, n, r and p should be required keyword-only parameters.
|
||||
They are optional in the Argument Clinic declaration only due to a
|
||||
limitation of PyArg_ParseTupleAndKeywords. */
|
||||
|
||||
/*[clinic input]
|
||||
_hashlib.scrypt
|
||||
|
||||
password: Py_buffer
|
||||
*
|
||||
salt: Py_buffer = None
|
||||
n as n_obj: object(subclass_of='&PyLong_Type') = None
|
||||
r as r_obj: object(subclass_of='&PyLong_Type') = None
|
||||
p as p_obj: object(subclass_of='&PyLong_Type') = None
|
||||
salt: Py_buffer
|
||||
n: unsigned_long
|
||||
r: unsigned_long
|
||||
p: unsigned_long
|
||||
maxmem: long = 0
|
||||
dklen: long = 64
|
||||
|
||||
@ -1410,14 +1406,13 @@ scrypt password-based key derivation function.
|
||||
|
||||
static PyObject *
|
||||
_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
|
||||
PyObject *n_obj, PyObject *r_obj, PyObject *p_obj,
|
||||
unsigned long n, unsigned long r, unsigned long p,
|
||||
long maxmem, long dklen)
|
||||
/*[clinic end generated code: output=14849e2aa2b7b46c input=48a7d63bf3f75c42]*/
|
||||
/*[clinic end generated code: output=d424bc3e8c6b9654 input=0c9a84230238fd79]*/
|
||||
{
|
||||
PyObject *key_obj = NULL;
|
||||
char *key;
|
||||
int retval;
|
||||
unsigned long n, r, p;
|
||||
|
||||
if (password->len > INT_MAX) {
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
@ -1425,43 +1420,18 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (salt->buf == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"salt is required");
|
||||
return NULL;
|
||||
}
|
||||
if (salt->len > INT_MAX) {
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"salt is too long.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n = PyLong_AsUnsignedLong(n_obj);
|
||||
if (n == (unsigned long) -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"n is required and must be an unsigned int");
|
||||
return NULL;
|
||||
}
|
||||
if (n < 2 || n & (n - 1)) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"n must be a power of 2.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = PyLong_AsUnsignedLong(r_obj);
|
||||
if (r == (unsigned long) -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"r is required and must be an unsigned int");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = PyLong_AsUnsignedLong(p_obj);
|
||||
if (p == (unsigned long) -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"p is required and must be an unsigned int");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (maxmem < 0 || maxmem > INT_MAX) {
|
||||
/* OpenSSL 1.1.0 restricts maxmem to 32 MiB. It may change in the
|
||||
future. The maxmem constant is private to OpenSSL. */
|
||||
|
70
Modules/clinic/_hashopenssl.c.h
generated
70
Modules/clinic/_hashopenssl.c.h
generated
@ -7,6 +7,7 @@ preserve
|
||||
# include "pycore_runtime.h" // _Py_ID()
|
||||
#endif
|
||||
#include "pycore_abstract.h" // _PyNumber_Index()
|
||||
#include "pycore_long.h" // _PyLong_UnsignedLong_Converter()
|
||||
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
|
||||
|
||||
PyDoc_STRVAR(EVP_copy__doc__,
|
||||
@ -1381,8 +1382,7 @@ exit:
|
||||
#if defined(PY_OPENSSL_HAS_SCRYPT)
|
||||
|
||||
PyDoc_STRVAR(_hashlib_scrypt__doc__,
|
||||
"scrypt($module, /, password, *, salt=None, n=None, r=None, p=None,\n"
|
||||
" maxmem=0, dklen=64)\n"
|
||||
"scrypt($module, /, password, *, salt, n, r, p, maxmem=0, dklen=64)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"scrypt password-based key derivation function.");
|
||||
@ -1392,7 +1392,7 @@ PyDoc_STRVAR(_hashlib_scrypt__doc__,
|
||||
|
||||
static PyObject *
|
||||
_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
|
||||
PyObject *n_obj, PyObject *r_obj, PyObject *p_obj,
|
||||
unsigned long n, unsigned long r, unsigned long p,
|
||||
long maxmem, long dklen);
|
||||
|
||||
static PyObject *
|
||||
@ -1427,64 +1427,38 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[7];
|
||||
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
|
||||
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 5;
|
||||
Py_buffer password = {NULL, NULL};
|
||||
Py_buffer salt = {NULL, NULL};
|
||||
PyObject *n_obj = Py_None;
|
||||
PyObject *r_obj = Py_None;
|
||||
PyObject *p_obj = Py_None;
|
||||
unsigned long n;
|
||||
unsigned long r;
|
||||
unsigned long p;
|
||||
long maxmem = 0;
|
||||
long dklen = 64;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
|
||||
/*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
|
||||
/*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 4, /*varpos*/ 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
if (PyObject_GetBuffer(args[0], &password, PyBUF_SIMPLE) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (PyObject_GetBuffer(args[1], &salt, PyBUF_SIMPLE) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyLong_UnsignedLong_Converter(args[2], &n)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyLong_UnsignedLong_Converter(args[3], &r)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyLong_UnsignedLong_Converter(args[4], &p)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
if (args[1]) {
|
||||
if (PyObject_GetBuffer(args[1], &salt, PyBUF_SIMPLE) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
if (args[2]) {
|
||||
if (!PyLong_Check(args[2])) {
|
||||
_PyArg_BadArgument("scrypt", "argument 'n'", "int", args[2]);
|
||||
goto exit;
|
||||
}
|
||||
n_obj = args[2];
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
if (args[3]) {
|
||||
if (!PyLong_Check(args[3])) {
|
||||
_PyArg_BadArgument("scrypt", "argument 'r'", "int", args[3]);
|
||||
goto exit;
|
||||
}
|
||||
r_obj = args[3];
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
if (args[4]) {
|
||||
if (!PyLong_Check(args[4])) {
|
||||
_PyArg_BadArgument("scrypt", "argument 'p'", "int", args[4]);
|
||||
goto exit;
|
||||
}
|
||||
p_obj = args[4];
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
if (args[5]) {
|
||||
maxmem = PyLong_AsLong(args[5]);
|
||||
if (maxmem == -1 && PyErr_Occurred()) {
|
||||
@ -1499,7 +1473,7 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
|
||||
goto exit;
|
||||
}
|
||||
skip_optional_kwonly:
|
||||
return_value = _hashlib_scrypt_impl(module, &password, &salt, n_obj, r_obj, p_obj, maxmem, dklen);
|
||||
return_value = _hashlib_scrypt_impl(module, &password, &salt, n, r, p, maxmem, dklen);
|
||||
|
||||
exit:
|
||||
/* Cleanup for password */
|
||||
@ -1897,4 +1871,4 @@ exit:
|
||||
#ifndef _HASHLIB_SCRYPT_METHODDEF
|
||||
#define _HASHLIB_SCRYPT_METHODDEF
|
||||
#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */
|
||||
/*[clinic end generated code: output=d908fa85e0251426 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=2c78822e38be64a8 input=a9049054013a1b77]*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user