give proper error message for invalid putpixel color type

This commit is contained in:
nulano 2020-08-19 23:43:43 +02:00
parent 8deaebd5e0
commit 4bb78d53a3
2 changed files with 43 additions and 11 deletions

View File

@ -328,6 +328,36 @@ class TestCffi(AccessTest):
assert im.convert("RGB").getpixel((0, 0)) == (255, 0, 0)
class TestImagePutPixelError(AccessTest):
def test_putpixel_error_message(self):
for mode, reason, accept_tuple in [
("L", "color must be int or tuple", True),
("LA", "color must be int or tuple", True),
("RGB", "color must be int or tuple", True),
("RGBA", "color must be int or tuple", True),
("I", "color must be int", False),
("I;16", "color must be int", False),
("BGR;15", "color must be int", False),
]:
im = hopper(mode)
for v in ["foo", 1.0, None]:
with pytest.raises(TypeError, match=reason):
im.putpixel((0, 0), v)
if not accept_tuple:
with pytest.raises(TypeError, match=reason):
im.putpixel((0, 0), (10,))
with pytest.raises(OverflowError):
im.putpixel((0, 0), 2 ** 80)
for mode in ["BGR;15"]:
im = hopper(mode)
with pytest.raises(ValueError, match="unrecognized image mode"):
im.putpixel((0, 0), 0)
class TestEmbeddable:
@pytest.mark.skipif(
not is_win32() or on_ci(),

View File

@ -521,12 +521,20 @@ getink(PyObject* color, Imaging im, char* ink)
if (im->type == IMAGING_TYPE_UINT8 ||
im->type == IMAGING_TYPE_INT32 ||
im->type == IMAGING_TYPE_SPECIAL) {
if (PyLong_Check(color)) {
r = PyLong_AsLongLong(color);
if (PyLong_Check(color)) {
r = PyLong_AsLongLong(color);
if (r == -1 && PyErr_Occurred()) {
return NULL;
}
rIsInt = 1;
}
if (r == -1 && PyErr_Occurred()) {
rIsInt = 0;
} else if (im->type == IMAGING_TYPE_UINT8) {
if (!PyTuple_Check(color)) {
PyErr_SetString(PyExc_TypeError, "color must be int or tuple");
return NULL;
}
} else {
PyErr_SetString(PyExc_TypeError, "color must be int");
return NULL;
}
}
@ -570,9 +578,6 @@ getink(PyObject* color, Imaging im, char* ink)
return ink;
case IMAGING_TYPE_INT32:
/* signed integer */
if (rIsInt != 1) {
return NULL;
}
itmp = r;
memcpy(ink, &itmp, sizeof(itmp));
return ink;
@ -587,9 +592,6 @@ getink(PyObject* color, Imaging im, char* ink)
return ink;
case IMAGING_TYPE_SPECIAL:
if (strncmp(im->mode, "I;16", 4) == 0) {
if (rIsInt != 1) {
return NULL;
}
ink[0] = (UINT8) r;
ink[1] = (UINT8) (r >> 8);
ink[2] = ink[3] = 0;