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
|
#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]
|
/*[clinic input]
|
||||||
_hashlib.scrypt
|
_hashlib.scrypt
|
||||||
|
|
||||||
password: Py_buffer
|
password: Py_buffer
|
||||||
*
|
*
|
||||||
salt: Py_buffer = None
|
salt: Py_buffer
|
||||||
n as n_obj: object(subclass_of='&PyLong_Type') = None
|
n: unsigned_long
|
||||||
r as r_obj: object(subclass_of='&PyLong_Type') = None
|
r: unsigned_long
|
||||||
p as p_obj: object(subclass_of='&PyLong_Type') = None
|
p: unsigned_long
|
||||||
maxmem: long = 0
|
maxmem: long = 0
|
||||||
dklen: long = 64
|
dklen: long = 64
|
||||||
|
|
||||||
@ -1410,14 +1406,13 @@ scrypt password-based key derivation function.
|
|||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
|
_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)
|
long maxmem, long dklen)
|
||||||
/*[clinic end generated code: output=14849e2aa2b7b46c input=48a7d63bf3f75c42]*/
|
/*[clinic end generated code: output=d424bc3e8c6b9654 input=0c9a84230238fd79]*/
|
||||||
{
|
{
|
||||||
PyObject *key_obj = NULL;
|
PyObject *key_obj = NULL;
|
||||||
char *key;
|
char *key;
|
||||||
int retval;
|
int retval;
|
||||||
unsigned long n, r, p;
|
|
||||||
|
|
||||||
if (password->len > INT_MAX) {
|
if (password->len > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
@ -1425,43 +1420,18 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (salt->buf == NULL) {
|
|
||||||
PyErr_SetString(PyExc_TypeError,
|
|
||||||
"salt is required");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (salt->len > INT_MAX) {
|
if (salt->len > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
"salt is too long.");
|
"salt is too long.");
|
||||||
return NULL;
|
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)) {
|
if (n < 2 || n & (n - 1)) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"n must be a power of 2.");
|
"n must be a power of 2.");
|
||||||
return NULL;
|
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) {
|
if (maxmem < 0 || maxmem > INT_MAX) {
|
||||||
/* OpenSSL 1.1.0 restricts maxmem to 32 MiB. It may change in the
|
/* OpenSSL 1.1.0 restricts maxmem to 32 MiB. It may change in the
|
||||||
future. The maxmem constant is private to OpenSSL. */
|
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()
|
# include "pycore_runtime.h" // _Py_ID()
|
||||||
#endif
|
#endif
|
||||||
#include "pycore_abstract.h" // _PyNumber_Index()
|
#include "pycore_abstract.h" // _PyNumber_Index()
|
||||||
|
#include "pycore_long.h" // _PyLong_UnsignedLong_Converter()
|
||||||
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
|
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
|
||||||
|
|
||||||
PyDoc_STRVAR(EVP_copy__doc__,
|
PyDoc_STRVAR(EVP_copy__doc__,
|
||||||
@ -1381,8 +1382,7 @@ exit:
|
|||||||
#if defined(PY_OPENSSL_HAS_SCRYPT)
|
#if defined(PY_OPENSSL_HAS_SCRYPT)
|
||||||
|
|
||||||
PyDoc_STRVAR(_hashlib_scrypt__doc__,
|
PyDoc_STRVAR(_hashlib_scrypt__doc__,
|
||||||
"scrypt($module, /, password, *, salt=None, n=None, r=None, p=None,\n"
|
"scrypt($module, /, password, *, salt, n, r, p, maxmem=0, dklen=64)\n"
|
||||||
" maxmem=0, dklen=64)\n"
|
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n"
|
"\n"
|
||||||
"scrypt password-based key derivation function.");
|
"scrypt password-based key derivation function.");
|
||||||
@ -1392,7 +1392,7 @@ PyDoc_STRVAR(_hashlib_scrypt__doc__,
|
|||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
|
_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);
|
long maxmem, long dklen);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
@ -1427,64 +1427,38 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
|
|||||||
};
|
};
|
||||||
#undef KWTUPLE
|
#undef KWTUPLE
|
||||||
PyObject *argsbuf[7];
|
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 password = {NULL, NULL};
|
||||||
Py_buffer salt = {NULL, NULL};
|
Py_buffer salt = {NULL, NULL};
|
||||||
PyObject *n_obj = Py_None;
|
unsigned long n;
|
||||||
PyObject *r_obj = Py_None;
|
unsigned long r;
|
||||||
PyObject *p_obj = Py_None;
|
unsigned long p;
|
||||||
long maxmem = 0;
|
long maxmem = 0;
|
||||||
long dklen = 64;
|
long dklen = 64;
|
||||||
|
|
||||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
|
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) {
|
if (!args) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (PyObject_GetBuffer(args[0], &password, PyBUF_SIMPLE) != 0) {
|
if (PyObject_GetBuffer(args[0], &password, PyBUF_SIMPLE) != 0) {
|
||||||
goto exit;
|
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) {
|
if (!noptargs) {
|
||||||
goto skip_optional_kwonly;
|
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]) {
|
if (args[5]) {
|
||||||
maxmem = PyLong_AsLong(args[5]);
|
maxmem = PyLong_AsLong(args[5]);
|
||||||
if (maxmem == -1 && PyErr_Occurred()) {
|
if (maxmem == -1 && PyErr_Occurred()) {
|
||||||
@ -1499,7 +1473,7 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
skip_optional_kwonly:
|
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:
|
exit:
|
||||||
/* Cleanup for password */
|
/* Cleanup for password */
|
||||||
@ -1897,4 +1871,4 @@ exit:
|
|||||||
#ifndef _HASHLIB_SCRYPT_METHODDEF
|
#ifndef _HASHLIB_SCRYPT_METHODDEF
|
||||||
#define _HASHLIB_SCRYPT_METHODDEF
|
#define _HASHLIB_SCRYPT_METHODDEF
|
||||||
#endif /* !defined(_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