Skip to content

Commit a64fdc7

Browse files
gh-132987: Support __index__() in the lzma module (GH-133099)
1 parent d2d4900 commit a64fdc7

File tree

2 files changed

+30
-24
lines changed

2 files changed

+30
-24
lines changed

Lib/test/test_lzma.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,10 +657,12 @@ def test_init_bad_preset(self):
657657
LZMAFile(BytesIO(), "w", preset=10)
658658
with self.assertRaises(LZMAError):
659659
LZMAFile(BytesIO(), "w", preset=23)
660-
with self.assertRaises(OverflowError):
660+
with self.assertRaises(ValueError):
661661
LZMAFile(BytesIO(), "w", preset=-1)
662-
with self.assertRaises(OverflowError):
662+
with self.assertRaises(ValueError):
663663
LZMAFile(BytesIO(), "w", preset=-7)
664+
with self.assertRaises(OverflowError):
665+
LZMAFile(BytesIO(), "w", preset=2**1000)
664666
with self.assertRaises(TypeError):
665667
LZMAFile(BytesIO(), "w", preset="foo")
666668
# Cannot specify a preset with mode="r".

Modules/_lzmamodule.c

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -203,25 +203,28 @@ PyLzma_Free(void *opaque, void *ptr)
203203
to be strictly correct, we need to define two separate converters.
204204
*/
205205

206-
#define INT_TYPE_CONVERTER_FUNC(TYPE, FUNCNAME) \
207-
static int \
208-
FUNCNAME(PyObject *obj, void *ptr) \
209-
{ \
210-
unsigned long long val; \
211-
\
212-
val = PyLong_AsUnsignedLongLong(obj); \
213-
if (PyErr_Occurred()) \
214-
return 0; \
215-
if ((unsigned long long)(TYPE)val != val) { \
216-
PyErr_SetString(PyExc_OverflowError, \
217-
"Value too large for " #TYPE " type"); \
218-
return 0; \
219-
} \
220-
*(TYPE *)ptr = (TYPE)val; \
221-
return 1; \
222-
}
206+
#define INT_TYPE_CONVERTER_FUNC(TYPE, FUNCNAME) \
207+
static int \
208+
FUNCNAME(PyObject *obj, void *ptr) \
209+
{ \
210+
Py_ssize_t bytes = PyLong_AsNativeBytes(obj, ptr, sizeof(TYPE), \
211+
Py_ASNATIVEBYTES_NATIVE_ENDIAN | \
212+
Py_ASNATIVEBYTES_ALLOW_INDEX | \
213+
Py_ASNATIVEBYTES_REJECT_NEGATIVE | \
214+
Py_ASNATIVEBYTES_UNSIGNED_BUFFER); \
215+
if (bytes < 0) { \
216+
return 0; \
217+
} \
218+
if ((size_t)bytes > sizeof(TYPE)) { \
219+
PyErr_SetString(PyExc_OverflowError, \
220+
"Python int too large for C "#TYPE); \
221+
return 0; \
222+
} \
223+
return 1; \
224+
}
223225

224226
INT_TYPE_CONVERTER_FUNC(uint32_t, uint32_converter)
227+
INT_TYPE_CONVERTER_FUNC(uint64_t, uint64_converter)
225228
INT_TYPE_CONVERTER_FUNC(lzma_vli, lzma_vli_converter)
226229
INT_TYPE_CONVERTER_FUNC(lzma_mode, lzma_mode_converter)
227230
INT_TYPE_CONVERTER_FUNC(lzma_match_finder, lzma_mf_converter)
@@ -355,11 +358,13 @@ lzma_filter_converter(_lzma_state *state, PyObject *spec, void *ptr)
355358
"Filter specifier must have an \"id\" entry");
356359
return 0;
357360
}
358-
f->id = PyLong_AsUnsignedLongLong(id_obj);
359-
Py_DECREF(id_obj);
360-
if (PyErr_Occurred()) {
361+
lzma_vli id;
362+
if (!lzma_vli_converter(id_obj, &id)) {
363+
Py_DECREF(id_obj);
361364
return 0;
362365
}
366+
Py_DECREF(id_obj);
367+
f->id = id;
363368

364369
switch (f->id) {
365370
case LZMA_FILTER_LZMA1:
@@ -1221,8 +1226,7 @@ _lzma_LZMADecompressor_impl(PyTypeObject *type, int format,
12211226
"Cannot specify memory limit with FORMAT_RAW");
12221227
return NULL;
12231228
}
1224-
memlimit_ = PyLong_AsUnsignedLongLong(memlimit);
1225-
if (PyErr_Occurred()) {
1229+
if (!uint64_converter(memlimit, &memlimit_)) {
12261230
return NULL;
12271231
}
12281232
}

0 commit comments

Comments
 (0)