Fix a bunch of signed overflow issues
authorSøren Sandmann Pedersen <ssp@redhat.com>
Wed, 21 Dec 2011 13:19:05 +0000 (08:19 -0500)
committerSøren Sandmann Pedersen <ssp@redhat.com>
Mon, 9 Jan 2012 10:40:33 +0000 (05:40 -0500)
In pixman-fast-path.c: (1 << 31) - 1 causes a signed overflow, so
change to (1U << n) - 1.

In pixman-image.c: The check for whether m10 == -m01 will overflow
when -m01 == INT_MIN. Instead just check whether the variables are 1
and -1.

In pixman-utils.c: When the depth of the topmost channel is 0, we can
end up shifting by 32.

In blitters-test.c: Replicating the mask would end up shifting more
than 32.

In region-contains-test.c: Computing the average of two large integers
could overflow. Instead add half the difference between them to the
first integer.

In stress-test.c: Masking the value in fake_reader() would sometimes
shift by 32. Instead just use the most significant bits instead of
the least significant.

All these issues were found by the IOC tool:

    http://embed.cs.utah.edu/ioc/

pixman/pixman-fast-path.c
pixman/pixman-image.c
pixman/pixman-utils.c
test/blitters-test.c
test/region-contains-test.c
test/stress-test.c

index 038dcf7..eac8dea 100644 (file)
@@ -1969,9 +1969,9 @@ static const pixman_fast_path_t c_fast_paths[] =
 };
 
 #ifdef WORDS_BIGENDIAN
-#define A1_FILL_MASK(n, offs) (((1 << (n)) - 1) << (32 - (offs) - (n)))
+#define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (32 - (offs) - (n)))
 #else
-#define A1_FILL_MASK(n, offs) (((1 << (n)) - 1) << (offs))
+#define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (offs))
 #endif
 
 static force_inline void
index ad5996b..8599a1e 100644 (file)
@@ -299,13 +299,12 @@ compute_image_info (pixman_image_t *image)
                     image->common.transform->matrix[1][1] == 0)
            {
                pixman_fixed_t m01 = image->common.transform->matrix[0][1];
-               if (m01 == -image->common.transform->matrix[1][0])
-               {
-                       if (m01 == -pixman_fixed_1)
-                           flags |= FAST_PATH_ROTATE_90_TRANSFORM;
-                       else if (m01 == pixman_fixed_1)
-                           flags |= FAST_PATH_ROTATE_270_TRANSFORM;
-               }
+               pixman_fixed_t m10 = image->common.transform->matrix[1][0];
+
+               if (m01 == -1 && m10 == 1)
+                   flags |= FAST_PATH_ROTATE_90_TRANSFORM;
+               else if (m01 == 1 && m10 == -1)
+                   flags |= FAST_PATH_ROTATE_270_TRANSFORM;
            }
        }
 
index d2af51a..2ec2594 100644 (file)
@@ -220,16 +220,33 @@ pixman_expand (uint64_t *           dst,
     for (i = width - 1; i >= 0; i--)
     {
        const uint32_t pixel = src[i];
-       const uint8_t a = (pixel >> a_shift) & a_mask,
-                     r = (pixel >> r_shift) & r_mask,
-                     g = (pixel >> g_shift) & g_mask,
-                     b = (pixel >> b_shift) & b_mask;
-       const uint64_t
-           a16 = a_size ? unorm_to_unorm (a, a_size, 16) : 0xffff,
-           r16 = unorm_to_unorm (r, r_size, 16),
-           g16 = unorm_to_unorm (g, g_size, 16),
-           b16 = unorm_to_unorm (b, b_size, 16);
+       uint8_t a, r, g, b;
+       uint64_t a16, r16, g16, b16;
+
+       if (a_size)
+       {
+           a = (pixel >> a_shift) & a_mask;
+           a16 = unorm_to_unorm (a, a_size, 16);
+       }
+       else
+       {
+           a16 = 0xffff;
+       }
 
+       if (r_size)
+       {
+           r = (pixel >> r_shift) & r_mask;
+           g = (pixel >> g_shift) & g_mask;
+           b = (pixel >> b_shift) & b_mask;
+           r16 = unorm_to_unorm (r, r_size, 16);
+           g16 = unorm_to_unorm (g, g_size, 16);
+           b16 = unorm_to_unorm (b, b_size, 16);
+       }
+       else
+       {
+           r16 = g16 = b16 = 0;
+       }
+       
        dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
     }
 }
index 63162e6..fd62c67 100644 (file)
@@ -103,7 +103,7 @@ free_random_image (uint32_t initcrc,
                mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
            }
 
-           for (i = 0; i < 32; i++)
+           for (i = 0; i * PIXMAN_FORMAT_BPP (fmt) < 32; i++)
                mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
 
            for (i = 0; i < stride * height / 4; i++)
index 2372686..9524e28 100644 (file)
@@ -73,7 +73,7 @@ random_coord (pixman_region32_t *region, pixman_bool_t x)
     case 3:
        return begin;
     default:
-       return (begin + end) / 2;
+       return (end - begin) / 2 + begin;
     }
     return 0;
 }
@@ -163,7 +163,7 @@ main (int argc, const char *argv[])
 {
     return fuzzer_test_main ("region_contains",
                             1000000,
-                            0xD7C297CC,
+                            0xD2BF8C73,
                             test_region_contains_rectangle,
                             argc, argv);
 }
index 08bf1d4..3174621 100644 (file)
@@ -166,7 +166,8 @@ fake_reader (const void *src, int size)
     uint32_t r = lcg_rand_u32 ();
 
     assert (size == 1 || size == 2 || size == 4);
-    return r & ((1 << (size * 8)) - 1);
+
+    return r >> (32 - (size * 8));
 }
 
 static void