diff --git a/CVE-2020-11538.patch b/CVE-2020-11538.patch new file mode 100644 index 0000000000000000000000000000000000000000..db2c68c9e440365c1f9ebec5e0ffbcb4c0ffd1f1 --- /dev/null +++ b/CVE-2020-11538.patch @@ -0,0 +1,55 @@ +From 394d6a180a4b63a149a223b13e98a3209f837147 Mon Sep 17 00:00:00 2001 +From: Eric Soroos +Date: Sat, 28 Mar 2020 13:00:46 +0000 +Subject: [PATCH 1/4] Track number of pixels, not the number of runs + +--- + src/libImaging/SgiRleDecode.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/libImaging/SgiRleDecode.c b/src/libImaging/SgiRleDecode.c +index e9b2c0b..087b7b4 100644 +--- a/src/libImaging/SgiRleDecode.c ++++ b/src/libImaging/SgiRleDecode.c +@@ -28,6 +28,7 @@ static void read4B(UINT32* dest, UINT8* buf) + static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize) + { + UINT8 pixel, count; ++ int x = 0; + + for (;n > 0; n--) + { +@@ -37,9 +38,10 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize) + count = pixel & RLE_MAX_RUN; + if (!count) + return count; +- if (count > xsize){ ++ if (x + count > xsize){ + return -1; + } ++ x += count; + if (pixel & RLE_COPY_FLAG) { + while(count--) { + *dest = *src++; +@@ -62,7 +64,8 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize) + static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize) + { + UINT8 pixel, count; +- ++ ++ int x = 0; + + for (;n > 0; n--) + { +@@ -73,9 +76,10 @@ static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize) + count = pixel & RLE_MAX_RUN; + if (!count) + return count; +- if (count > xsize){ ++ if (x + count > xsize){ + return -1; + } ++ x += count; + if (pixel & RLE_COPY_FLAG) { + while(count--) { + memcpy(dest, src, 2); diff --git a/pre-CVE-2020-11538-1.patch b/pre-CVE-2020-11538-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..088112a4127ac887b29e064366b9ca8eb2441dfe --- /dev/null +++ b/pre-CVE-2020-11538-1.patch @@ -0,0 +1,1604 @@ +From 7a4af2b7671b14163f61c7f88889fad66e50d77b Mon Sep 17 00:00:00 2001 +From: Rolf Eike Beer +Date: Sun, 1 Jul 2018 12:47:59 +0200 +Subject: [PATCH] fix unaligned accesses by using memcpy() + +--- + src/_imaging.c | 31 ++++-- + src/libImaging/Access.c | 24 ++-- + src/libImaging/Bands.c | 30 +++-- + src/libImaging/ColorLUT.c | 10 +- + src/libImaging/Convert.c | 165 +++++++++++++++------------ + src/libImaging/Filter.c | 32 ++++-- + src/libImaging/Geometry.c | 18 ++- + src/libImaging/GetBBox.c | 26 +++-- + src/libImaging/Histo.c | 10 +- + src/libImaging/Pack.c | 13 ++- + src/libImaging/Point.c | 16 ++- + src/libImaging/Resample.c | 30 +++-- + src/libImaging/SgiRleDecode.c | 19 ++-- + src/libImaging/Unpack.c | 203 +++++++++++++++++----------------- + 14 files changed, 357 insertions(+), 270 deletions(-) + +diff --git a/src/_imaging.c b/src/_imaging.c +index e4b31f1..56fa0b6 100644 +--- a/src/_imaging.c ++++ b/src/_imaging.c +@@ -374,7 +374,8 @@ getlist(PyObject* arg, Py_ssize_t* length, const char* wrong_length, int type) + Py_ssize_t i, n; + int itemp; + double dtemp; +- void* list; ++ FLOAT32 ftemp; ++ UINT8* list; + PyObject* seq; + PyObject* op; + +@@ -408,19 +409,19 @@ getlist(PyObject* arg, Py_ssize_t* length, const char* wrong_length, int type) + switch (type) { + case TYPE_UINT8: + itemp = PyInt_AsLong(op); +- ((UINT8*)list)[i] = CLIP8(itemp); ++ list[i] = CLIP8(itemp); + break; + case TYPE_INT32: + itemp = PyInt_AsLong(op); +- ((INT32*)list)[i] = itemp; ++ memcpy(list + i * sizeof(INT32), &itemp, sizeof(itemp)); + break; + case TYPE_FLOAT32: +- dtemp = PyFloat_AsDouble(op); +- ((FLOAT32*)list)[i] = (FLOAT32) dtemp; ++ ftemp = (FLOAT32)PyFloat_AsDouble(op); ++ memcpy(list + i * sizeof(ftemp), &ftemp, sizeof(ftemp)); + break; + case TYPE_DOUBLE: + dtemp = PyFloat_AsDouble(op); +- ((double*)list)[i] = (double) dtemp; ++ memcpy(list + i * sizeof(dtemp), &dtemp, sizeof(dtemp)); + break; + } + } +@@ -517,6 +518,8 @@ getink(PyObject* color, Imaging im, char* ink) + to return it into a 32 bit C long + */ + PY_LONG_LONG r = 0; ++ FLOAT32 ftmp; ++ INT32 itmp; + + /* fill ink buffer (four bytes) with something that can + be cast to either UINT8 or INT32 */ +@@ -582,14 +585,16 @@ getink(PyObject* color, Imaging im, char* ink) + /* signed integer */ + if (rIsInt != 1) + return NULL; +- *(INT32*) ink = r; ++ itmp = r; ++ memcpy(ink, &itmp, sizeof(itmp)); + return ink; + case IMAGING_TYPE_FLOAT32: + /* floating point */ + f = PyFloat_AsDouble(color); + if (f == -1.0 && PyErr_Occurred()) + return NULL; +- *(FLOAT32*) ink = (FLOAT32) f; ++ ftmp = f; ++ memcpy(ink, &ftmp, sizeof(ftmp)); + return ink; + case IMAGING_TYPE_SPECIAL: + if (strncmp(im->mode, "I;16", 4) == 0) { +@@ -784,15 +789,19 @@ _prepare_lut_table(PyObject* table, Py_ssize_t table_size) + } + + for (i = 0; i < table_size; i++) { ++ FLOAT16 htmp; ++ double dtmp; + switch (data_type) { + case TYPE_FLOAT16: +- item = float16tofloat32(((FLOAT16*) table_data)[i]); ++ memcpy(&htmp, ((char*) table_data) + i * sizeof(htmp), sizeof(htmp)); ++ item = float16tofloat32(htmp); + break; + case TYPE_FLOAT32: +- item = ((FLOAT32*) table_data)[i]; ++ memcpy(&item, ((char*) table_data) + i * sizeof(FLOAT32), sizeof(FLOAT32)); + break; + case TYPE_DOUBLE: +- item = ((double*) table_data)[i]; ++ memcpy(&dtmp, ((char*) table_data) + i * sizeof(dtmp), sizeof(dtmp)); ++ item = (FLOAT32) dtmp; + break; + } + /* Max value for INT16 */ +diff --git a/src/libImaging/Access.c b/src/libImaging/Access.c +index 292968f..47b0345 100644 +--- a/src/libImaging/Access.c ++++ b/src/libImaging/Access.c +@@ -94,11 +94,11 @@ static void + get_pixel_16L(Imaging im, int x, int y, void* color) + { + UINT8* in = (UINT8*) &im->image[y][x+x]; +- UINT16* out = color; + #ifdef WORDS_BIGENDIAN +- out[0] = in[0] + (in[1]<<8); ++ UINT16 out = in[0] + (in[1]<<8); ++ memcpy(color, &out, sizeof(out)); + #else +- out[0] = *(UINT16*) in; ++ memcpy(color, in, sizeof(UINT16)); + #endif + } + +@@ -106,11 +106,11 @@ static void + get_pixel_16B(Imaging im, int x, int y, void* color) + { + UINT8* in = (UINT8*) &im->image[y][x+x]; +- UINT16* out = color; + #ifdef WORDS_BIGENDIAN +- out[0] = *(UINT16*) in; ++ memcpy(color, in, sizeof(UINT16)); + #else +- out[0] = in[1] + (in[0]<<8); ++ UINT16 out = in[1] + (in[0]<<8); ++ memcpy(color, &out, sizeof(out)); + #endif + } + +@@ -125,11 +125,11 @@ static void + get_pixel_32L(Imaging im, int x, int y, void* color) + { + UINT8* in = (UINT8*) &im->image[y][x*4]; +- INT32* out = color; + #ifdef WORDS_BIGENDIAN +- out[0] = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24); ++ INT32 out = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24); ++ memcpy(color, &out, sizeof(out)); + #else +- out[0] = *(INT32*) in; ++ memcpy(color, in, sizeof(INT32)); + #endif + } + +@@ -137,11 +137,11 @@ static void + get_pixel_32B(Imaging im, int x, int y, void* color) + { + UINT8* in = (UINT8*) &im->image[y][x*4]; +- INT32* out = color; + #ifdef WORDS_BIGENDIAN +- out[0] = *(INT32*) in; ++ memcpy(color, in, sizeof(INT32)); + #else +- out[0] = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24); ++ INT32 out = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24); ++ memcpy(color, &out, sizeof(out)); + #endif + } + +diff --git a/src/libImaging/Bands.c b/src/libImaging/Bands.c +index e38e228..7fff044 100644 +--- a/src/libImaging/Bands.c ++++ b/src/libImaging/Bands.c +@@ -50,7 +50,8 @@ ImagingGetBand(Imaging imIn, int band) + UINT8* out = imOut->image8[y]; + x = 0; + for (; x < imIn->xsize - 3; x += 4) { +- *((UINT32*) (out + x)) = MAKE_UINT32(in[0], in[4], in[8], in[12]); ++ UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]); ++ memcpy(out + x, &v, sizeof(v)); + in += 16; + } + for (; x < imIn->xsize; x++) { +@@ -98,8 +99,10 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) + UINT8* out1 = bands[1]->image8[y]; + x = 0; + for (; x < imIn->xsize - 3; x += 4) { +- *((UINT32*) (out0 + x)) = MAKE_UINT32(in[0], in[4], in[8], in[12]); +- *((UINT32*) (out1 + x)) = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]); ++ UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]); ++ memcpy(out0 + x, &v, sizeof(v)); ++ v = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]); ++ memcpy(out1 + x, &v, sizeof(v)); + in += 16; + } + for (; x < imIn->xsize; x++) { +@@ -116,9 +119,12 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) + UINT8* out2 = bands[2]->image8[y]; + x = 0; + for (; x < imIn->xsize - 3; x += 4) { +- *((UINT32*) (out0 + x)) = MAKE_UINT32(in[0], in[4], in[8], in[12]); +- *((UINT32*) (out1 + x)) = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]); +- *((UINT32*) (out2 + x)) = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]); ++ UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]); ++ memcpy(out0 + x, &v, sizeof(v)); ++ v = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]); ++ memcpy(out1 + x, &v, sizeof(v)); ++ v = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]); ++ memcpy(out2 + x, &v, sizeof(v)); + in += 16; + } + for (; x < imIn->xsize; x++) { +@@ -137,10 +143,14 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) + UINT8* out3 = bands[3]->image8[y]; + x = 0; + for (; x < imIn->xsize - 3; x += 4) { +- *((UINT32*) (out0 + x)) = MAKE_UINT32(in[0], in[4], in[8], in[12]); +- *((UINT32*) (out1 + x)) = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]); +- *((UINT32*) (out2 + x)) = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]); +- *((UINT32*) (out3 + x)) = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]); ++ UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]); ++ memcpy(out0 + x, &v, sizeof(v)); ++ v = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]); ++ memcpy(out1 + x, &v, sizeof(v)); ++ v = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]); ++ memcpy(out2 + x, &v, sizeof(v)); ++ v = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]); ++ memcpy(out3 + x, &v, sizeof(v)); + in += 16; + } + for (; x < imIn->xsize; x++) { +diff --git a/src/libImaging/ColorLUT.c b/src/libImaging/ColorLUT.c +index 46b0014..f01d389 100644 +--- a/src/libImaging/ColorLUT.c ++++ b/src/libImaging/ColorLUT.c +@@ -105,7 +105,7 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels, + ImagingSectionEnter(&cookie); + for (y = 0; y < imOut->ysize; y++) { + UINT8* rowIn = (UINT8 *)imIn->image[y]; +- UINT32* rowOut = (UINT32 *)imOut->image[y]; ++ char* rowOut = (char *)imOut->image[y]; + for (x = 0; x < imOut->xsize; x++) { + UINT32 index1D = rowIn[x*4 + 0] * scale1D; + UINT32 index2D = rowIn[x*4 + 1] * scale2D; +@@ -120,6 +120,7 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels, + INT16 leftleft[4], leftright[4], rightleft[4], rightright[4]; + + if (table_channels == 3) { ++ UINT32 v; + interpolate3(leftleft, &table[idx + 0], &table[idx + 3], shift1D); + interpolate3(leftright, &table[idx + size1D*3], + &table[idx + size1D*3 + 3], shift1D); +@@ -133,12 +134,14 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels, + + interpolate3(result, left, right, shift3D); + +- rowOut[x] = MAKE_UINT32( ++ v = MAKE_UINT32( + clip8(result[0]), clip8(result[1]), + clip8(result[2]), rowIn[x*4 + 3]); ++ memcpy(rowOut + x * sizeof(v), &v, sizeof(v)); + } + + if (table_channels == 4) { ++ UINT32 v; + interpolate4(leftleft, &table[idx + 0], &table[idx + 4], shift1D); + interpolate4(leftright, &table[idx + size1D*4], + &table[idx + size1D*4 + 4], shift1D); +@@ -152,9 +155,10 @@ ImagingColorLUT3D_linear(Imaging imOut, Imaging imIn, int table_channels, + + interpolate4(result, left, right, shift3D); + +- rowOut[x] = MAKE_UINT32( ++ v = MAKE_UINT32( + clip8(result[0]), clip8(result[1]), + clip8(result[2]), clip8(result[3])); ++ memcpy(rowOut + x * sizeof(v), &v, sizeof(v)); + } + } + } +diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c +index 39ddf87..b7b6a80 100644 +--- a/src/libImaging/Convert.c ++++ b/src/libImaging/Convert.c +@@ -229,42 +229,46 @@ static void + rgb2i(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- INT32* out = (INT32*) out_; +- for (x = 0; x < xsize; x++, in += 4) +- *out++ = L24(in) >> 16; ++ for (x = 0; x < xsize; x++, in += 4, out_ += 4) { ++ INT32 v = L24(in) >> 16; ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void + rgb2f(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- FLOAT32* out = (FLOAT32*) out_; +- for (x = 0; x < xsize; x++, in += 4) +- *out++ = (float) L(in) / 1000.0F; ++ for (x = 0; x < xsize; x++, in += 4, out_ += 4) { ++ FLOAT32 v = (float) L(in) / 1000.0F; ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void + rgb2bgr15(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- UINT16* out = (UINT16*) out_; +- for (x = 0; x < xsize; x++, in += 4) +- *out++ = ++ for (x = 0; x < xsize; x++, in += 4, out_ += 2) { ++ UINT16 v = + ((((UINT16)in[0])<<7)&0x7c00) + + ((((UINT16)in[1])<<2)&0x03e0) + + ((((UINT16)in[2])>>3)&0x001f); ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void + rgb2bgr16(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- UINT16* out = (UINT16*) out_; +- for (x = 0; x < xsize; x++, in += 4) +- *out++ = ++ for (x = 0; x < xsize; x++, in += 4, out_ += 2) { ++ UINT16 v = + ((((UINT16)in[0])<<8)&0xf800) + + ((((UINT16)in[1])<<3)&0x07e0) + + ((((UINT16)in[2])>>3)&0x001f); ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void +@@ -490,12 +494,13 @@ rgbT2rgba(UINT8* out, int xsize, int r, int g, int b) + UINT32 repl = trns & 0x00ffffff; + #endif + +- UINT32* tmp = (UINT32 *)out; + int i; + +- for (i=0; i < xsize; i++ ,tmp++) { +- if (tmp[0]==trns) { +- tmp[0]=repl; ++ for (i=0; i < xsize; i++ ,out += sizeof(trns)) { ++ UINT32 v; ++ memcpy(&v, out, sizeof(v)); ++ if (v==trns) { ++ memcpy(out, &repl, sizeof(repl)); + } + } + } +@@ -553,32 +558,35 @@ static void + bit2i(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- INT32* out = (INT32*) out_; +- for (x = 0; x < xsize; x++) +- *out++ = (*in++ != 0) ? 255 : 0; ++ for (x = 0; x < xsize; x++, out_ += 4) { ++ INT32 v = (*in++ != 0) ? 255 : 0; ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void + l2i(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- INT32* out = (INT32*) out_; +- for (x = 0; x < xsize; x++) +- *out++ = (INT32) *in++; ++ for (x = 0; x < xsize; x++, out_ += 4) { ++ INT32 v = *in++; ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void + i2l(UINT8* out, const UINT8* in_, int xsize) + { + int x; +- INT32* in = (INT32*) in_; +- for (x = 0; x < xsize; x++, in++, out++) { +- if (*in <= 0) ++ for (x = 0; x < xsize; x++, out++, in_ += 4) { ++ INT32 v; ++ memcpy(&v, in_, sizeof(v)); ++ if (v <= 0) + *out = 0; +- else if (*in >= 255) ++ else if (v >= 255) + *out = 255; + else +- *out = (UINT8) *in; ++ *out = (UINT8) v; + } + } + +@@ -586,10 +594,13 @@ static void + i2f(UINT8* out_, const UINT8* in_, int xsize) + { + int x; +- INT32* in = (INT32*) in_; +- FLOAT32* out = (FLOAT32*) out_; +- for (x = 0; x < xsize; x++) +- *out++ = (FLOAT32) *in++; ++ for (x = 0; x < xsize; x++, in_ += 4, out_ += 4) { ++ INT32 i; ++ FLOAT32 f; ++ memcpy(&i, in_, sizeof(i)); ++ f = i; ++ memcpy(out_, &f, sizeof(f)); ++ } + } + + /* ------------- */ +@@ -600,32 +611,35 @@ static void + bit2f(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- FLOAT32* out = (FLOAT32*) out_; +- for (x = 0; x < xsize; x++) +- *out++ = (*in++ != 0) ? 255.0F : 0.0F; ++ for (x = 0; x < xsize; x++, out_ += 4) { ++ FLOAT32 f = (*in++ != 0) ? 255.0F : 0.0F; ++ memcpy(out_, &f, sizeof(f)); ++ } + } + + static void + l2f(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- FLOAT32* out = (FLOAT32*) out_; +- for (x = 0; x < xsize; x++) +- *out++ = (FLOAT32) *in++; ++ for (x = 0; x < xsize; x++, out_ += 4) { ++ FLOAT32 f = (FLOAT32) *in++; ++ memcpy(out_, &f, sizeof(f)); ++ } + } + + static void + f2l(UINT8* out, const UINT8* in_, int xsize) + { + int x; +- FLOAT32* in = (FLOAT32*) in_; +- for (x = 0; x < xsize; x++, in++, out++) { +- if (*in <= 0.0) ++ for (x = 0; x < xsize; x++, out++, in_ += 4) { ++ FLOAT32 v; ++ memcpy(&v, in_, sizeof(v)); ++ if (v <= 0.0) + *out = 0; +- else if (*in >= 255.0) ++ else if (v >= 255.0) + *out = 255; + else +- *out = (UINT8) *in; ++ *out = (UINT8) v; + } + } + +@@ -633,10 +647,13 @@ static void + f2i(UINT8* out_, const UINT8* in_, int xsize) + { + int x; +- FLOAT32* in = (FLOAT32*) in_; +- INT32* out = (INT32*) out_; +- for (x = 0; x < xsize; x++) +- *out++ = (INT32) *in++; ++ for (x = 0; x < xsize; x++, in_ += 4, out_ += 4) { ++ FLOAT32 f; ++ INT32 i; ++ memcpy(&f, in_, sizeof(f)); ++ i = f; ++ memcpy(out_, &i, sizeof(i)); ++ } + } + + /* ----------------- */ +@@ -673,9 +690,10 @@ static void + I_I16L(UINT8* out, const UINT8* in_, int xsize) + { + int x, v; +- INT32* in = (INT32*) in_; +- for (x = 0; x < xsize; x++, in++) { +- v = CLIP16(*in); ++ for (x = 0; x < xsize; x++, in_ += 4) { ++ INT32 i; ++ memcpy(&i, in_, sizeof(i)); ++ v = CLIP16(i); + *out++ = (UINT8) v; + *out++ = (UINT8) (v >> 8); + } +@@ -685,9 +703,10 @@ static void + I_I16B(UINT8* out, const UINT8* in_, int xsize) + { + int x, v; +- INT32* in = (INT32*) in_; +- for (x = 0; x < xsize; x++, in++) { +- v = CLIP16(*in); ++ for (x = 0; x < xsize; x++, in_ += 4) { ++ INT32 i; ++ memcpy(&i, in_, sizeof(i)); ++ v = CLIP16(i); + *out++ = (UINT8) (v >> 8); + *out++ = (UINT8) v; + } +@@ -698,9 +717,10 @@ static void + I16L_I(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- INT32* out = (INT32*) out_; +- for (x = 0; x < xsize; x++, in += 2) +- *out++ = in[0] + ((int) in[1] << 8); ++ for (x = 0; x < xsize; x++, in += 2, out_ += 4) { ++ INT32 v = in[0] + ((int) in[1] << 8); ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + +@@ -708,18 +728,20 @@ static void + I16B_I(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- INT32* out = (INT32*) out_; +- for (x = 0; x < xsize; x++, in += 2) +- *out++ = in[1] + ((int) in[0] << 8); ++ for (x = 0; x < xsize; x++, in += 2, out_ += 4) { ++ INT32 v = in[1] + ((int) in[0] << 8); ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void + I16L_F(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- FLOAT32* out = (FLOAT32*) out_; +- for (x = 0; x < xsize; x++, in += 2) +- *out++ = (FLOAT32) (in[0] + ((int) in[1] << 8)); ++ for (x = 0; x < xsize; x++, in += 2, out_ += 4) { ++ FLOAT32 v = in[0] + ((int) in[1] << 8); ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + +@@ -727,9 +749,10 @@ static void + I16B_F(UINT8* out_, const UINT8* in, int xsize) + { + int x; +- FLOAT32* out = (FLOAT32*) out_; +- for (x = 0; x < xsize; x++, in += 2) +- *out++ = (FLOAT32) (in[1] + ((int) in[0] << 8)); ++ for (x = 0; x < xsize; x++, in += 2, out_ += 4) { ++ FLOAT32 v = in[1] + ((int) in[0] << 8); ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void +@@ -930,18 +953,20 @@ static void + p2i(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) + { + int x; +- INT32* out = (INT32*) out_; +- for (x = 0; x < xsize; x++) +- *out++ = L(&palette[in[x]*4]) / 1000; ++ for (x = 0; x < xsize; x++, in += 2, out_ += 4) { ++ INT32 v = L(&palette[in[x]*4]) / 1000; ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void + p2f(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) + { + int x; +- FLOAT32* out = (FLOAT32*) out_; +- for (x = 0; x < xsize; x++) +- *out++ = (float) L(&palette[in[x]*4]) / 1000.0F; ++ for (x = 0; x < xsize; x++, in += 2, out_ += 4) { ++ FLOAT32 v = L(&palette[in[x]*4]) / 1000.0F; ++ memcpy(out_, &v, sizeof(v)); ++ } + } + + static void +diff --git a/src/libImaging/Filter.c b/src/libImaging/Filter.c +index 6e4a005..7d88cd7 100644 +--- a/src/libImaging/Filter.c ++++ b/src/libImaging/Filter.c +@@ -122,26 +122,29 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel, + UINT8* in_1 = (UINT8*) im->image[y-1]; + UINT8* in0 = (UINT8*) im->image[y]; + UINT8* in1 = (UINT8*) im->image[y+1]; +- UINT32* out = (UINT32*) imOut->image[y]; ++ UINT8* out = (UINT8*) imOut->image[y]; + +- out[0] = ((UINT32*) in0)[0]; ++ memcpy(out, in0, sizeof(UINT32)); + if (im->bands == 2) { + for (x = 1; x < im->xsize-1; x++) { + float ss0 = offset; + float ss3 = offset; ++ UINT32 v; + ss0 += KERNEL1x3(in1, x*4+0, &kernel[0], 4); + ss3 += KERNEL1x3(in1, x*4+3, &kernel[0], 4); + ss0 += KERNEL1x3(in0, x*4+0, &kernel[3], 4); + ss3 += KERNEL1x3(in0, x*4+3, &kernel[3], 4); + ss0 += KERNEL1x3(in_1, x*4+0, &kernel[6], 4); + ss3 += KERNEL1x3(in_1, x*4+3, &kernel[6], 4); +- out[x] = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); ++ v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); ++ memcpy(out + x * sizeof(v), &v, sizeof(v)); + } + } else if (im->bands == 3) { + for (x = 1; x < im->xsize-1; x++) { + float ss0 = offset; + float ss1 = offset; + float ss2 = offset; ++ UINT32 v; + ss0 += KERNEL1x3(in1, x*4+0, &kernel[0], 4); + ss1 += KERNEL1x3(in1, x*4+1, &kernel[0], 4); + ss2 += KERNEL1x3(in1, x*4+2, &kernel[0], 4); +@@ -151,8 +154,9 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel, + ss0 += KERNEL1x3(in_1, x*4+0, &kernel[6], 4); + ss1 += KERNEL1x3(in_1, x*4+1, &kernel[6], 4); + ss2 += KERNEL1x3(in_1, x*4+2, &kernel[6], 4); +- out[x] = MAKE_UINT32( ++ v = MAKE_UINT32( + clip8(ss0), clip8(ss1), clip8(ss2), 0); ++ memcpy(out + x * sizeof(v), &v, sizeof(v)); + } + } else if (im->bands == 4) { + for (x = 1; x < im->xsize-1; x++) { +@@ -160,6 +164,7 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel, + float ss1 = offset; + float ss2 = offset; + float ss3 = offset; ++ UINT32 v; + ss0 += KERNEL1x3(in1, x*4+0, &kernel[0], 4); + ss1 += KERNEL1x3(in1, x*4+1, &kernel[0], 4); + ss2 += KERNEL1x3(in1, x*4+2, &kernel[0], 4); +@@ -172,11 +177,12 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel, + ss1 += KERNEL1x3(in_1, x*4+1, &kernel[6], 4); + ss2 += KERNEL1x3(in_1, x*4+2, &kernel[6], 4); + ss3 += KERNEL1x3(in_1, x*4+3, &kernel[6], 4); +- out[x] = MAKE_UINT32( ++ v = MAKE_UINT32( + clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); ++ memcpy(out + x * sizeof(v), &v, sizeof(v)); + } + } +- out[x] = ((UINT32*) in0)[x]; ++ memcpy(out + x * sizeof(UINT32), in0 + x * sizeof(UINT32), sizeof(UINT32)); + } + } + memcpy(imOut->image[y], im->image[y], im->linesize); +@@ -240,6 +246,7 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, + for (x = 2; x < im->xsize-2; x++) { + float ss0 = offset; + float ss3 = offset; ++ UINT32 v; + ss0 += KERNEL1x5(in2, x*4+0, &kernel[0], 4); + ss3 += KERNEL1x5(in2, x*4+3, &kernel[0], 4); + ss0 += KERNEL1x5(in1, x*4+0, &kernel[5], 4); +@@ -250,13 +257,15 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, + ss3 += KERNEL1x5(in_1, x*4+3, &kernel[15], 4); + ss0 += KERNEL1x5(in_2, x*4+0, &kernel[20], 4); + ss3 += KERNEL1x5(in_2, x*4+3, &kernel[20], 4); +- out[x] = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); ++ v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); ++ memcpy(out + x * sizeof(v), &v, sizeof(v)); + } + } else if (im->bands == 3) { + for (x = 2; x < im->xsize-2; x++) { + float ss0 = offset; + float ss1 = offset; + float ss2 = offset; ++ UINT32 v; + ss0 += KERNEL1x5(in2, x*4+0, &kernel[0], 4); + ss1 += KERNEL1x5(in2, x*4+1, &kernel[0], 4); + ss2 += KERNEL1x5(in2, x*4+2, &kernel[0], 4); +@@ -272,8 +281,9 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, + ss0 += KERNEL1x5(in_2, x*4+0, &kernel[20], 4); + ss1 += KERNEL1x5(in_2, x*4+1, &kernel[20], 4); + ss2 += KERNEL1x5(in_2, x*4+2, &kernel[20], 4); +- out[x] = MAKE_UINT32( ++ v = MAKE_UINT32( + clip8(ss0), clip8(ss1), clip8(ss2), 0); ++ memcpy(out + x * sizeof(v), &v, sizeof(v)); + } + } else if (im->bands == 4) { + for (x = 2; x < im->xsize-2; x++) { +@@ -281,6 +291,7 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, + float ss1 = offset; + float ss2 = offset; + float ss3 = offset; ++ UINT32 v; + ss0 += KERNEL1x5(in2, x*4+0, &kernel[0], 4); + ss1 += KERNEL1x5(in2, x*4+1, &kernel[0], 4); + ss2 += KERNEL1x5(in2, x*4+2, &kernel[0], 4); +@@ -301,12 +312,12 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float* kernel, + ss1 += KERNEL1x5(in_2, x*4+1, &kernel[20], 4); + ss2 += KERNEL1x5(in_2, x*4+2, &kernel[20], 4); + ss3 += KERNEL1x5(in_2, x*4+3, &kernel[20], 4); +- out[x] = MAKE_UINT32( ++ v = MAKE_UINT32( + clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); ++ memcpy(out + x * sizeof(v), &v, sizeof(v)); + } + } +- out[x] = ((UINT32*) in0)[x]; +- out[x+1] = ((UINT32*) in0)[x+1]; ++ memcpy(out + x * sizeof(UINT32), in0 + x * sizeof(UINT32), sizeof(UINT32) * 2); + } + } + memcpy(imOut->image[y], im->image[y], im->linesize); +diff --git a/src/libImaging/Geometry.c b/src/libImaging/Geometry.c +index 1d08728..52ca9fc 100644 +--- a/src/libImaging/Geometry.c ++++ b/src/libImaging/Geometry.c +@@ -396,7 +396,7 @@ nearest_filter16(void* out, Imaging im, double xin, double yin) + int y = COORD(yin); + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) + return 0; +- ((INT16*)out)[0] = ((INT16*)(im->image8[y]))[x]; ++ memcpy(out, im->image8[y] + x * sizeof(INT16), sizeof(INT16)); + return 1; + } + +@@ -457,18 +457,22 @@ bilinear_filter8(void* out, Imaging im, double xin, double yin) + static int + bilinear_filter32I(void* out, Imaging im, double xin, double yin) + { ++ INT32 k; + BILINEAR_HEAD(INT32); + BILINEAR_BODY(INT32, im->image32, 1, 0); +- ((INT32*)out)[0] = (INT32) v1; ++ k = v1; ++ memcpy(out, &k, sizeof(k)); + return 1; + } + + static int + bilinear_filter32F(void* out, Imaging im, double xin, double yin) + { ++ FLOAT32 k; + BILINEAR_HEAD(FLOAT32); + BILINEAR_BODY(FLOAT32, im->image32, 1, 0); +- ((FLOAT32*)out)[0] = (FLOAT32) v1; ++ k = v1; ++ memcpy(out, &k, sizeof(k)); + return 1; + } + +@@ -569,18 +573,22 @@ bicubic_filter8(void* out, Imaging im, double xin, double yin) + static int + bicubic_filter32I(void* out, Imaging im, double xin, double yin) + { ++ INT32 k; + BICUBIC_HEAD(INT32); + BICUBIC_BODY(INT32, im->image32, 1, 0); +- ((INT32*)out)[0] = (INT32) v1; ++ k = v1; ++ memcpy(out, &k, sizeof(k)); + return 1; + } + + static int + bicubic_filter32F(void* out, Imaging im, double xin, double yin) + { ++ FLOAT32 k; + BICUBIC_HEAD(FLOAT32); + BICUBIC_BODY(FLOAT32, im->image32, 1, 0); +- ((FLOAT32*)out)[0] = (FLOAT32) v1; ++ k = v1; ++ memcpy(out, &k, sizeof(k)); + return 1; + } + +diff --git a/src/libImaging/GetBBox.c b/src/libImaging/GetBBox.c +index 3cfa42c..7f01e16 100644 +--- a/src/libImaging/GetBBox.c ++++ b/src/libImaging/GetBBox.c +@@ -132,8 +132,8 @@ ImagingGetExtrema(Imaging im, void *extrema) + imax = in[x]; + } + } +- ((UINT8*) extrema)[0] = (UINT8) imin; +- ((UINT8*) extrema)[1] = (UINT8) imax; ++ memcpy(extrema, &imin, sizeof(imin)); ++ memcpy(((char*)extrema) + sizeof(imin), &imax, sizeof(imax)); + break; + case IMAGING_TYPE_INT32: + imin = imax = im->image32[0][0]; +@@ -165,18 +165,22 @@ ImagingGetExtrema(Imaging im, void *extrema) + break; + case IMAGING_TYPE_SPECIAL: + if (strcmp(im->mode, "I;16") == 0) { +- imin = imax = ((UINT16*) im->image8[0])[0]; ++ UINT16 v; ++ memcpy(&v, *im->image8, sizeof(v)); ++ imin = imax = v; + for (y = 0; y < im->ysize; y++) { +- UINT16* in = (UINT16 *) im->image[y]; + for (x = 0; x < im->xsize; x++) { +- if (imin > in[x]) +- imin = in[x]; +- else if (imax < in[x]) +- imax = in[x]; +- } ++ memcpy(&v, im->image[y] + x * sizeof(v), sizeof(v)); ++ if (imin > v) ++ imin = v; ++ else if (imax < v) ++ imax = v; ++ } + } +- ((UINT16*) extrema)[0] = (UINT16) imin; +- ((UINT16*) extrema)[1] = (UINT16) imax; ++ v = (UINT16) imin; ++ memcpy(extrema, &v, sizeof(v)); ++ v = (UINT16) imax; ++ memcpy(((char*)extrema) + sizeof(v), &v, sizeof(v)); + break; + } + /* FALL THROUGH */ +diff --git a/src/libImaging/Histo.c b/src/libImaging/Histo.c +index 0bfc8df..7ba0ee0 100644 +--- a/src/libImaging/Histo.c ++++ b/src/libImaging/Histo.c +@@ -124,8 +124,8 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax) + return ImagingError_ValueError("min/max not given"); + if (!im->xsize || !im->ysize) + break; +- imin = ((INT32*) minmax)[0]; +- imax = ((INT32*) minmax)[1]; ++ memcpy(&imin, minmax, sizeof(imin)); ++ memcpy(&imax, ((char*)minmax) + sizeof(imin), sizeof(imax)); + if (imin >= imax) + break; + ImagingSectionEnter(&cookie); +@@ -145,9 +145,9 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax) + return ImagingError_ValueError("min/max not given"); + if (!im->xsize || !im->ysize) + break; +- fmin = ((FLOAT32*) minmax)[0]; +- fmax = ((FLOAT32*) minmax)[1]; +- if (fmin >= fmax) ++ memcpy(&fmin, minmax, sizeof(fmin)); ++ memcpy(&fmax, ((char*)minmax) + sizeof(fmin), sizeof(fmax)); ++ if (fmin >= fmax) + break; + ImagingSectionEnter(&cookie); + scale = 255.0F / (fmax - fmin); +diff --git a/src/libImaging/Pack.c b/src/libImaging/Pack.c +index 5c298c6..d18f31c 100644 +--- a/src/libImaging/Pack.c ++++ b/src/libImaging/Pack.c +@@ -252,7 +252,7 @@ ImagingPackRGB(UINT8* out, const UINT8* in, int pixels) + int i = 0; + /* RGB triplets */ + for (; i < pixels-1; i++) { +- ((UINT32*)out)[0] = ((UINT32*)in)[i]; ++ memcpy(out, in + i * 4, 4); + out += 3; + } + for (; i < pixels; i++) { +@@ -392,18 +392,19 @@ static void + packI16B(UINT8* out, const UINT8* in_, int pixels) + { + int i; +- INT32* in = (INT32*) in_; + UINT16 tmp_; + UINT8* tmp = (UINT8*) &tmp_; + for (i = 0; i < pixels; i++) { +- if (in[0] <= 0) ++ INT32 in; ++ memcpy(&in, in_, sizeof(in)); ++ if (in <= 0) + tmp_ = 0; +- else if (in[0] > 65535) ++ else if (in > 65535) + tmp_ = 65535; + else +- tmp_ = in[0]; ++ tmp_ = in; + C16B; +- out += 2; in++; ++ out += 2; in_ += sizeof(in); + } + } + +diff --git a/src/libImaging/Point.c b/src/libImaging/Point.c +index 426c410..9b4bf6b 100644 +--- a/src/libImaging/Point.c ++++ b/src/libImaging/Point.c +@@ -99,12 +99,12 @@ im_point_8_32(Imaging imOut, Imaging imIn, im_point_context* context) + { + int x, y; + /* 8-bit source, 32-bit destination */ +- INT32* table = (INT32*) context->table; ++ char* table = (char*) context->table; + for (y = 0; y < imIn->ysize; y++) { + UINT8* in = imIn->image8[y]; + INT32* out = imOut->image32[y]; + for (x = 0; x < imIn->xsize; x++) +- out[x] = table[in[x]]; ++ memcpy(out + x, table + in[x] * sizeof(INT32), sizeof(INT32)); + } + } + +@@ -242,11 +242,15 @@ ImagingPointTransform(Imaging imIn, double scale, double offset) + if (strcmp(imIn->mode,"I;16") == 0) { + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) { +- UINT16* in = (UINT16 *)imIn->image[y]; +- UINT16* out = (UINT16 *)imOut->image[y]; ++ char* in = (char*)imIn->image[y]; ++ char* out = (char*)imOut->image[y]; + /* FIXME: add clipping? */ +- for (x = 0; x < imIn->xsize; x++) +- out[x] = in[x] * scale + offset; ++ for (x = 0; x < imIn->xsize; x++) { ++ UINT16 v; ++ memcpy(&v, in + x * sizeof(v), sizeof(v)); ++ v = v * scale + offset; ++ memcpy(out + x * sizeof(UINT16), &v, sizeof(v)); ++ } + } + ImagingSectionLeave(&cookie); + break; +diff --git a/src/libImaging/Resample.c b/src/libImaging/Resample.c +index 6fae208..d1a89e2 100644 +--- a/src/libImaging/Resample.c ++++ b/src/libImaging/Resample.c +@@ -304,6 +304,7 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset, + if (imIn->bands == 2) { + for (yy = 0; yy < imOut->ysize; yy++) { + for (xx = 0; xx < imOut->xsize; xx++) { ++ UINT32 v; + xmin = bounds[xx * 2 + 0]; + xmax = bounds[xx * 2 + 1]; + k = &kk[xx * ksize]; +@@ -312,13 +313,14 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset, + ss0 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 0]) * k[x]; + ss3 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 3]) * k[x]; + } +- ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( +- clip8(ss0), 0, 0, clip8(ss3)); ++ v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); ++ memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); + } + } + } else if (imIn->bands == 3) { + for (yy = 0; yy < imOut->ysize; yy++) { + for (xx = 0; xx < imOut->xsize; xx++) { ++ UINT32 v; + xmin = bounds[xx * 2 + 0]; + xmax = bounds[xx * 2 + 1]; + k = &kk[xx * ksize]; +@@ -328,13 +330,14 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset, + ss1 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 1]) * k[x]; + ss2 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 2]) * k[x]; + } +- ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( +- clip8(ss0), clip8(ss1), clip8(ss2), 0); ++ v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0); ++ memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); + } + } + } else { + for (yy = 0; yy < imOut->ysize; yy++) { + for (xx = 0; xx < imOut->xsize; xx++) { ++ UINT32 v; + xmin = bounds[xx * 2 + 0]; + xmax = bounds[xx * 2 + 1]; + k = &kk[xx * ksize]; +@@ -345,8 +348,8 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset, + ss2 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 2]) * k[x]; + ss3 += ((UINT8) imIn->image[yy + offset][(x + xmin)*4 + 3]) * k[x]; + } +- ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( +- clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); ++ v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); ++ memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); + } + } + } +@@ -388,13 +391,14 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset, + ymin = bounds[yy * 2 + 0]; + ymax = bounds[yy * 2 + 1]; + for (xx = 0; xx < imOut->xsize; xx++) { ++ UINT32 v; + ss0 = ss3 = 1 << (PRECISION_BITS -1); + for (y = 0; y < ymax; y++) { + ss0 += ((UINT8) imIn->image[y + ymin][xx*4 + 0]) * k[y]; + ss3 += ((UINT8) imIn->image[y + ymin][xx*4 + 3]) * k[y]; + } +- ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( +- clip8(ss0), 0, 0, clip8(ss3)); ++ v = MAKE_UINT32(clip8(ss0), 0, 0, clip8(ss3)); ++ memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); + } + } + } else if (imIn->bands == 3) { +@@ -403,14 +407,15 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset, + ymin = bounds[yy * 2 + 0]; + ymax = bounds[yy * 2 + 1]; + for (xx = 0; xx < imOut->xsize; xx++) { ++ UINT32 v; + ss0 = ss1 = ss2 = 1 << (PRECISION_BITS -1); + for (y = 0; y < ymax; y++) { + ss0 += ((UINT8) imIn->image[y + ymin][xx*4 + 0]) * k[y]; + ss1 += ((UINT8) imIn->image[y + ymin][xx*4 + 1]) * k[y]; + ss2 += ((UINT8) imIn->image[y + ymin][xx*4 + 2]) * k[y]; + } +- ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( +- clip8(ss0), clip8(ss1), clip8(ss2), 0); ++ v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), 0); ++ memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); + } + } + } else { +@@ -419,6 +424,7 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset, + ymin = bounds[yy * 2 + 0]; + ymax = bounds[yy * 2 + 1]; + for (xx = 0; xx < imOut->xsize; xx++) { ++ UINT32 v; + ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS -1); + for (y = 0; y < ymax; y++) { + ss0 += ((UINT8) imIn->image[y + ymin][xx*4 + 0]) * k[y]; +@@ -426,8 +432,8 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset, + ss2 += ((UINT8) imIn->image[y + ymin][xx*4 + 2]) * k[y]; + ss3 += ((UINT8) imIn->image[y + ymin][xx*4 + 3]) * k[y]; + } +- ((UINT32 *) imOut->image[yy])[xx] = MAKE_UINT32( +- clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); ++ v = MAKE_UINT32(clip8(ss0), clip8(ss1), clip8(ss2), clip8(ss3)); ++ memcpy(imOut->image[yy] + xx * sizeof(v), &v, sizeof(v)); + } + } + } +diff --git a/src/libImaging/SgiRleDecode.c b/src/libImaging/SgiRleDecode.c +index 39e7b3a..70b0ec5 100644 +--- a/src/libImaging/SgiRleDecode.c ++++ b/src/libImaging/SgiRleDecode.c +@@ -56,15 +56,15 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z) + return 0; + } + +-static int expandrow2(UINT16* dest, UINT16* src, int n, int z) ++static int expandrow2(UINT8* dest, const UINT8* src, int n, int z) + { + UINT8 pixel, count; + + + for (;n > 0; n--) + { +- pixel = ((UINT8*)src)[1]; +- ++src; ++ pixel = src[1]; ++ src+=2; + if (n == 1 && pixel != 0) + return n; + count = pixel & RLE_MAX_RUN; +@@ -72,16 +72,17 @@ static int expandrow2(UINT16* dest, UINT16* src, int n, int z) + return count; + if (pixel & RLE_COPY_FLAG) { + while(count--) { +- *dest = *src++; +- dest += z; ++ memcpy(dest, src, 2); ++ src += 2; ++ dest += z * 2; + } + } + else { + while (count--) { +- *dest = *src; +- dest += z; ++ memcpy(dest, src, 2); ++ dest += z * 2; + } +- ++src; ++ src+=2; + } + } + return 0; +@@ -167,7 +168,7 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state, + goto sgi_finish_decode; + } + else { +- if(expandrow2((UINT16*)&state->buffer[c->channo * 2], (UINT16*)&ptr[c->rleoffset], c->rlelength, im->bands)) ++ if(expandrow2(&state->buffer[c->channo * 2], &ptr[c->rleoffset], c->rlelength, im->bands)) + goto sgi_finish_decode; + } + +diff --git a/src/libImaging/Unpack.c b/src/libImaging/Unpack.c +index e9921d2..28c9cf1 100644 +--- a/src/libImaging/Unpack.c ++++ b/src/libImaging/Unpack.c +@@ -32,7 +32,6 @@ + + #include "Imaging.h" + +- + #define R 0 + #define G 1 + #define B 2 +@@ -327,11 +326,11 @@ static void + unpackLA(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* LA, pixel interleaved */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[0], in[0], in[0], in[1]); +- in += 2; ++ UINT32 iv = MAKE_UINT32(in[0], in[0], in[0], in[1]); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 2; _out += 4; + } + } + +@@ -339,10 +338,10 @@ static void + unpackLAL(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* LA, line interleaved */ +- for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[i], in[i], in[i], in[i+pixels]); ++ for (i = 0; i < pixels; i++, _out+=4) { ++ UINT32 iv = MAKE_UINT32(in[i], in[i], in[i], in[i+pixels]); ++ memcpy(_out, &iv, sizeof(iv)); + } + } + +@@ -480,15 +479,18 @@ void + ImagingUnpackRGB(UINT8* _out, const UINT8* in, int pixels) + { + int i = 0; +- UINT32* out = (UINT32*) _out; + /* RGB triplets */ + for (; i < pixels-1; i++) { +- out[i] = MASK_UINT32_CHANNEL_3 | *(UINT32*)&in[0]; +- in += 3; ++ UINT32 iv; ++ memcpy(&iv, in, sizeof(iv)); ++ iv |= MASK_UINT32_CHANNEL_3; ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 3; _out += 4; + } + for (; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[0], in[1], in[2], 255); +- in += 3; ++ UINT32 iv = MAKE_UINT32(in[0], in[1], in[2], 255); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 3; _out += 4; + } + } + +@@ -508,11 +510,11 @@ void + unpackRGB16B(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* 16-bit RGB triplets, big-endian order */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[0], in[2], in[4], 255); +- in += 6; ++ UINT32 iv = MAKE_UINT32(in[0], in[2], in[4], 255); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 6; _out += 4; + } + } + +@@ -520,10 +522,10 @@ static void + unpackRGBL(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGB, line interleaved */ +- for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], 255); ++ for (i = 0; i < pixels; i++, _out+=4) { ++ UINT32 iv = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], 255); ++ memcpy(_out, &iv, sizeof(iv)); + } + } + +@@ -531,12 +533,12 @@ static void + unpackRGBR(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGB, bit reversed */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(BITFLIP[in[0]], BITFLIP[in[1]], +- BITFLIP[in[2]], 255); +- in += 3; ++ UINT32 iv = MAKE_UINT32(BITFLIP[in[0]], BITFLIP[in[1]], ++ BITFLIP[in[2]], 255); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 3; _out += 4; + } + } + +@@ -544,11 +546,11 @@ void + ImagingUnpackBGR(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGB, reversed bytes */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[2], in[1], in[0], 255); +- in += 3; ++ UINT32 iv = MAKE_UINT32(in[2], in[1], in[0], 255); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 3; _out += 4; + } + } + +@@ -676,11 +678,11 @@ static void + ImagingUnpackBGRX(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGB, reversed bytes with padding */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[2], in[1], in[0], 255); +- in += 4; ++ UINT32 iv = MAKE_UINT32(in[2], in[1], in[0], 255); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -688,11 +690,11 @@ static void + ImagingUnpackXRGB(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGB, leading pad */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[1], in[2], in[3], 255); +- in += 4; ++ UINT32 iv = MAKE_UINT32(in[1], in[2], in[3], 255); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -700,11 +702,11 @@ static void + ImagingUnpackXBGR(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGB, reversed bytes, leading pad */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[3], in[2], in[1], 255); +- in += 4; ++ UINT32 iv = MAKE_UINT32(in[3], in[2], in[1], 255); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -714,11 +716,11 @@ static void + unpackRGBALA(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* greyscale with alpha */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[0], in[0], in[0], in[1]); +- in += 2; ++ UINT32 iv = MAKE_UINT32(in[0], in[0], in[0], in[1]); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 2; _out += 4; + } + } + +@@ -726,11 +728,11 @@ static void + unpackRGBALA16B(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* 16-bit greyscale with alpha, big-endian */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[0], in[0], in[0], in[2]); +- in += 4; ++ UINT32 iv = MAKE_UINT32(in[0], in[0], in[0], in[2]); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -738,20 +740,21 @@ static void + unpackRGBa16L(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* premultiplied 16-bit RGBA, little-endian */ + for (i = 0; i < pixels; i++) { + int a = in[7]; ++ UINT32 iv; + if ( ! a) { +- out[i] = 0; ++ iv = 0; + } else if (a == 255) { +- out[i] = MAKE_UINT32(in[1], in[3], in[5], a); ++ iv = MAKE_UINT32(in[1], in[3], in[5], a); + } else { +- out[i] = MAKE_UINT32(CLIP8(in[1] * 255 / a), +- CLIP8(in[3] * 255 / a), +- CLIP8(in[5] * 255 / a), a); ++ iv = MAKE_UINT32(CLIP8(in[1] * 255 / a), ++ CLIP8(in[3] * 255 / a), ++ CLIP8(in[5] * 255 / a), a); + } +- in += 8; ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 8; _out += 4; + } + } + +@@ -759,20 +762,21 @@ static void + unpackRGBa16B(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* premultiplied 16-bit RGBA, big-endian */ + for (i = 0; i < pixels; i++) { + int a = in[6]; ++ UINT32 iv; + if ( ! a) { +- out[i] = 0; ++ iv = 0; + } else if (a == 255) { +- out[i] = MAKE_UINT32(in[0], in[2], in[4], a); ++ iv = MAKE_UINT32(in[0], in[2], in[4], a); + } else { +- out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a), +- CLIP8(in[2] * 255 / a), +- CLIP8(in[4] * 255 / a), a); ++ iv = MAKE_UINT32(CLIP8(in[0] * 255 / a), ++ CLIP8(in[2] * 255 / a), ++ CLIP8(in[4] * 255 / a), a); + } +- in += 8; ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 8; _out += 4; + } + } + +@@ -780,20 +784,21 @@ static void + unpackRGBa(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* premultiplied RGBA */ + for (i = 0; i < pixels; i++) { + int a = in[3]; ++ UINT32 iv; + if ( ! a) { +- out[i] = 0; ++ iv = 0; + } else if (a == 255) { +- out[i] = MAKE_UINT32(in[0], in[1], in[2], a); ++ iv = MAKE_UINT32(in[0], in[1], in[2], a); + } else { +- out[i] = MAKE_UINT32(CLIP8(in[0] * 255 / a), +- CLIP8(in[1] * 255 / a), +- CLIP8(in[2] * 255 / a), a); ++ iv = MAKE_UINT32(CLIP8(in[0] * 255 / a), ++ CLIP8(in[1] * 255 / a), ++ CLIP8(in[2] * 255 / a), a); + } +- in += 4; ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -843,20 +848,21 @@ static void + unpackBGRa(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* premultiplied BGRA */ + for (i = 0; i < pixels; i++) { + int a = in[3]; ++ UINT32 iv; + if ( ! a) { +- out[i] = 0; ++ iv = 0; + } else if (a == 255) { +- out[i] = MAKE_UINT32(in[2], in[1], in[0], a); ++ iv = MAKE_UINT32(in[2], in[1], in[0], a); + } else { +- out[i] = MAKE_UINT32(CLIP8(in[2] * 255 / a), +- CLIP8(in[1] * 255 / a), +- CLIP8(in[0] * 255 / a), a); ++ iv = MAKE_UINT32(CLIP8(in[2] * 255 / a), ++ CLIP8(in[1] * 255 / a), ++ CLIP8(in[0] * 255 / a), a); + } +- in += 4; ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -878,11 +884,11 @@ static void + unpackRGBAL(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGBA, line interleaved */ +- for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], +- in[i+pixels+pixels+pixels]); ++ for (i = 0; i < pixels; i++, _out+=4) { ++ UINT32 iv = MAKE_UINT32(in[i], in[i+pixels], in[i+pixels+pixels], ++ in[i+pixels+pixels+pixels]); ++ memcpy(_out, &iv, sizeof(iv)); + } + } + +@@ -890,10 +896,10 @@ void + unpackRGBA16L(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* 16-bit RGBA, little-endian order */ +- for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[1], in[3], in[5], in[7]); ++ for (i = 0; i < pixels; i++, _out+=4) { ++ UINT32 iv = MAKE_UINT32(in[1], in[3], in[5], in[7]); ++ memcpy(_out, &iv, sizeof(iv)); + in += 8; + } + } +@@ -902,10 +908,10 @@ void + unpackRGBA16B(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* 16-bit RGBA, big-endian order */ +- for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[0], in[2], in[4], in[6]); ++ for (i = 0; i < pixels; i++, _out+=4) { ++ UINT32 iv = MAKE_UINT32(in[0], in[2], in[4], in[6]); ++ memcpy(_out, &iv, sizeof(iv)); + in += 8; + } + } +@@ -914,11 +920,11 @@ static void + unpackARGB(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGBA, leading pad */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[1], in[2], in[3], in[0]); +- in += 4; ++ UINT32 iv = MAKE_UINT32(in[1], in[2], in[3], in[0]); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -926,11 +932,11 @@ static void + unpackABGR(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGBA, reversed bytes */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[3], in[2], in[1], in[0]); +- in += 4; ++ UINT32 iv = MAKE_UINT32(in[3], in[2], in[1], in[0]); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -938,11 +944,11 @@ static void + unpackBGRA(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* RGBA, reversed bytes */ + for (i = 0; i < pixels; i++) { +- out[i] = MAKE_UINT32(in[2], in[1], in[0], in[3]); +- in += 4; ++ UINT32 iv = MAKE_UINT32(in[2], in[1], in[0], in[3]); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -953,11 +959,11 @@ static void + unpackCMYKI(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + /* CMYK, inverted bytes (Photoshop 2.5) */ + for (i = 0; i < pixels; i++) { +- out[i] = ~MAKE_UINT32(in[0], in[1], in[2], in[3]); +- in += 4; ++ UINT32 iv = ~MAKE_UINT32(in[0], in[1], in[2], in[3]); ++ memcpy(_out, &iv, sizeof(iv)); ++ in += 4; _out += 4; + } + } + +@@ -1031,30 +1037,30 @@ unpackI12_I16(UINT8* out, const UINT8* in, int pixels){ + #ifdef WORDS_BIGENDIAN + UINT8* tmp = (UINT8 *)&pixel; + #endif +- UINT16* out16 = (UINT16 *)out; + for (i = 0; i < pixels-1; i+=2) { + pixel = (((UINT16) in[0]) << 4 ) + (in[1] >>4); + #ifdef WORDS_BIGENDIAN + out[0] = tmp[1]; out[1] = tmp[0]; + #else +- out16[0] = pixel; ++ memcpy(out, &pixel, sizeof(pixel)); + #endif + ++ out+=2; + pixel = (((UINT16) (in[1] & 0x0F)) << 8) + in[2]; + #ifdef WORDS_BIGENDIAN +- out[2] = tmp[1]; out[3] = tmp[0]; ++ out[0] = tmp[1]; out[1] = tmp[0]; + #else +- out16[1] = pixel; ++ memcpy(out, &pixel, sizeof(pixel)); + #endif + +- in += 3; out16 += 2; out+=4; ++ in += 3; out+=2; + } + if (i == pixels-1) { + pixel = (((UINT16) in[0]) << 4 ) + (in[1] >>4); + #ifdef WORDS_BIGENDIAN + out[0] = tmp[1]; out[1] = tmp[0]; + #else +- out16[0] = pixel; ++ memcpy(out, &pixel, sizeof(pixel)); + #endif + } + } +@@ -1085,10 +1091,9 @@ static void + copy4skip1(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + for (i = 0; i < pixels; i++) { +- out[i] = *(UINT32*)&in[0]; +- in += 5; ++ memcpy(_out, in, 4); ++ in += 5; _out += 4; + } + } + +@@ -1096,10 +1101,9 @@ static void + copy4skip2(UINT8* _out, const UINT8* in, int pixels) + { + int i; +- UINT32* out = (UINT32*) _out; + for (i = 0; i < pixels; i++) { +- out[i] = *(UINT32*)&in[0]; +- in += 6; ++ memcpy(_out, in, 4); ++ in += 6; _out += 4; + } + } + diff --git a/pre-CVE-2020-11538-2.patch b/pre-CVE-2020-11538-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..44a8468ac66c7f940754c22b71070fe2ea8a29e3 --- /dev/null +++ b/pre-CVE-2020-11538-2.patch @@ -0,0 +1,82 @@ +From be44f0d9923485f3ed3a7a9fd479cf8cf69d814a Mon Sep 17 00:00:00 2001 +From: Andrew Murray +Date: Wed, 1 Jan 2020 14:16:45 +1100 +Subject: [PATCH] Catch SGI buffer overruns + +--- + Tests/test_image.py | 2 ++ + src/libImaging/SgiRleDecode.c | 23 +++++++++++++++++------ + 4 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/src/libImaging/SgiRleDecode.c b/src/libImaging/SgiRleDecode.c +index 70b0ec5..e9b2c0b 100644 +--- a/src/libImaging/SgiRleDecode.c ++++ b/src/libImaging/SgiRleDecode.c +@@ -25,7 +25,7 @@ static void read4B(UINT32* dest, UINT8* buf) + *dest = (UINT32)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]); + } + +-static int expandrow(UINT8* dest, UINT8* src, int n, int z) ++static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize) + { + UINT8 pixel, count; + +@@ -37,6 +37,9 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z) + count = pixel & RLE_MAX_RUN; + if (!count) + return count; ++ if (count > xsize){ ++ return -1; ++ } + if (pixel & RLE_COPY_FLAG) { + while(count--) { + *dest = *src++; +@@ -56,7 +59,7 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z) + return 0; + } + +-static int expandrow2(UINT8* dest, const UINT8* src, int n, int z) ++static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize) + { + UINT8 pixel, count; + +@@ -70,6 +73,9 @@ static int expandrow2(UINT8* dest, const UINT8* src, int n, int z) + count = pixel & RLE_MAX_RUN; + if (!count) + return count; ++ if (count > xsize){ ++ return -1; ++ } + if (pixel & RLE_COPY_FLAG) { + while(count--) { + memcpy(dest, src, 2); +@@ -96,6 +102,7 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state, + UINT8 *ptr; + SGISTATE *c; + int err = 0; ++ int status; + + /* Get all data from File descriptor */ + c = (SGISTATE*)state->context; +@@ -164,13 +171,17 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state, + + /* row decompression */ + if (c->bpc ==1) { +- if(expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands)) +- goto sgi_finish_decode; ++ status = expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize); + } + else { +- if(expandrow2(&state->buffer[c->channo * 2], &ptr[c->rleoffset], c->rlelength, im->bands)) +- goto sgi_finish_decode; ++ status = expandrow2(&state->buffer[c->channo * 2], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize); + } ++ if (status == -1) { ++ state->errcode = IMAGING_CODEC_OVERRUN; ++ return -1; ++ } else if (status == 1) { ++ goto sgi_finish_decode; ++ } + + state->count += c->rlelength; + } diff --git a/python-pillow.spec b/python-pillow.spec index d2592b130c8bcb26dd455ff7dbda2d216b835e8a..367eda56b23e619c17bcdd9376c288e19eee42ec 100644 --- a/python-pillow.spec +++ b/python-pillow.spec @@ -5,7 +5,7 @@ Name: python-pillow Version: 5.3.0 -Release: 6 +Release: 7 Summary: Python image processing library License: MIT URL: http://python-pillow.github.io/ @@ -18,6 +18,9 @@ Patch0003: 0003-CVE-2019-16865-4.patch Patch0004: CVE-2020-10378.patch Patch0005: CVE-2020-10177.patch Patch0006: CVE-2020-10994.patch +Patch0007: pre-CVE-2020-11538-1.patch +Patch0008: pre-CVE-2020-11538-2.patch +Patch0009: CVE-2020-11538.patch BuildRequires: freetype-devel ghostscript lcms2-devel libimagequant-devel libjpeg-devel BuildRequires: libtiff-devel libwebp-devel openjpeg2-devel tk-devel zlib-devel @@ -171,6 +174,12 @@ popd %doc docs/_build_py3/html %changelog +* Sun Sep 13 2020 shixuantong - 5.3.0-7 +- Type:cves +- ID:CVE-2020-11538 +- SUG:NA +- DESC:fix CVE-2020-11538 + * Sat Sep 12 2020 shixuantong - 5.3.0-6 - Type:cves - ID:CVE-2020-10378 CVE-2020-10177 CVE-2020-10994