Skip to content

Commit a3c5e80

Browse files
committed
runtime: fix UB in int.frombytes
1 parent 0dd6c2d commit a3c5e80

1 file changed

Lines changed: 15 additions & 18 deletions

File tree

src/runtime/PyInteger.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
#include <gmpxx.h>
1515

16+
#include <ranges>
17+
1618
namespace py {
1719

1820
template<> PyInteger *as(PyObject *obj)
@@ -38,14 +40,10 @@ PyInteger::PyInteger(TypePrototype &type, BigIntType value)
3840
{}
3941

4042
PyInteger::PyInteger(PyType *type, BigIntType value) : PyInteger(type)
41-
{
42-
m_value = Number{ std::move(value) };
43-
}
43+
{ m_value = Number{ std::move(value) }; }
4444

4545
PyResult<PyInteger *> PyInteger::create(int64_t value)
46-
{
47-
return PyInteger::create(BigIntType{ value });
48-
}
46+
{ return PyInteger::create(BigIntType{ value }); }
4947

5048
PyResult<PyInteger *> PyInteger::create(BigIntType value)
5149
{
@@ -197,9 +195,7 @@ PyResult<PyObject *> PyInteger::__rshift__(const PyObject *obj) const
197195
}
198196

199197
PyResult<PyObject *> PyInteger::bit_length() const
200-
{
201-
return PyInteger::create(mpz_sizeinbase(as_big_int().get_mpz_t(), 2));
202-
}
198+
{ return PyInteger::create(mpz_sizeinbase(as_big_int().get_mpz_t(), 2)); }
203199

204200
PyResult<PyObject *> PyInteger::bit_count() const
205201
{
@@ -299,9 +295,10 @@ PyResult<PyObject *> PyInteger::from_bytes(PyType *type, PyTuple *args, PyDict *
299295
value |= static_cast<uint64_t>(bytes->value().b[i]) << i * 8;
300296
}
301297
} else {
302-
for (size_t i = 0; i < bytes->value().b.size(); ++i) {
303-
value |= static_cast<uint64_t>(bytes->value().b[i])
304-
<< ((sizeof(uint64_t) * 8) - ((i - 1) * 8));
298+
const auto &bytes_ = bytes->value().b;
299+
for (size_t i = 0; auto el : bytes_ | std::ranges::views::reverse) {
300+
value |= static_cast<uint64_t>(el) << i * 8;
301+
++i;
305302
}
306303
}
307304

@@ -362,12 +359,12 @@ namespace {
362359
std::unique_ptr<TypePrototype> register_int()
363360
{
364361
return std::move(klass<PyInteger>("int")
365-
.def("bit_length", &PyInteger::bit_length)
366-
.def("bit_count", &PyInteger::bit_count)
367-
.def("to_bytes", &PyInteger::to_bytes)
368-
.def("__round__", &PyInteger::__round__)
369-
.classmethod("from_bytes", &PyInteger::from_bytes)
370-
.type);
362+
.def("bit_length", &PyInteger::bit_length)
363+
.def("bit_count", &PyInteger::bit_count)
364+
.def("to_bytes", &PyInteger::to_bytes)
365+
.def("__round__", &PyInteger::__round__)
366+
.classmethod("from_bytes", &PyInteger::from_bytes)
367+
.type);
371368
}
372369
}// namespace
373370

0 commit comments

Comments
 (0)