int stride;
int buf_size;
int bpp;
-
+
+ /* what follows is a long-winded way, avoiding any possibility of integer
+ * overflows, of saying:
+ * stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (uint32_t);
+ */
+
bpp = PIXMAN_FORMAT_BPP (format);
- stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (uint32_t);
+ if (pixman_multiply_overflows_int (width, bpp))
+ return NULL;
+
+ stride = width * bpp;
+ if (pixman_addition_overflows_int (stride, FB_MASK))
+ return NULL;
+
+ stride += FB_MASK;
+ stride >>= FB_SHIFT;
+
+#if FB_SHIFT < 2
+ if (pixman_multiply_overflows_int (stride, sizeof (uint32_t)))
+ return NULL;
+#endif
+ stride *= sizeof (uint32_t);
+
+ if (pixman_multiply_overflows_int (height, stride))
+ return NULL;
+
buf_size = height * stride;
if (rowstride_bytes)
/* Memory allocation helpers */
void *pixman_malloc_ab (unsigned int n, unsigned int b);
void *pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
+pixman_bool_t pixman_multiply_overflows_int (unsigned int a, unsigned int b);
+pixman_bool_t pixman_addition_overflows_int (unsigned int a, unsigned int b);
#if DEBUG
bot->y + y_off_fixed);
}
+pixman_bool_t
+pixman_multiply_overflows_int (unsigned int a,
+ unsigned int b)
+{
+ return a >= INT32_MAX / b;
+}
+
+pixman_bool_t
+pixman_addition_overflows_int (unsigned int a,
+ unsigned int b)
+{
+ return a > INT32_MAX - b;
+}
+
void *
pixman_malloc_ab(unsigned int a,
unsigned int b)