summaryrefslogtreecommitdiff
path: root/pngpriv.h
diff options
context:
space:
mode:
authorJohn Bowler <jbowler@acm.org>2016-09-30 18:37:22 -0700
committerJohn Bowler <jbowler@acm.org>2016-09-30 18:37:22 -0700
commit319c9852bf65a5ff587328ec9f1e3a7873f8d044 (patch)
treece41ea17e9c298157d788df0e6351c3e6bbc5c6b /pngpriv.h
parent04dab1e82db2b6b038cda57a1918e132da6e58b5 (diff)
downloadlibpng-319c9852bf65a5ff587328ec9f1e3a7873f8d044.tar.gz
Unsigned overflow
Remove all currently detected cases of unsigned overflow. Detection is runtime, so test case dependent. The changes to pngvalid.c eliminate spurious and probably invalid tests with one while loop exception. Apart from that and the change to the dependence on the intended unsigned overflow in pngtrans.c the changes are limited to altering the meme for an unsigned 'x' from: while (x-- > 0) to for (; x > 0; --x) This works because, in all cases, the control variable is not used in the loop. The 'while' meme was, at one time, warn'ed by GCC so it is probably a good change, for some weird religious value of good. Signed-off-by: John Bowler <jbowler@acm.org>
Diffstat (limited to 'pngpriv.h')
-rw-r--r--pngpriv.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/pngpriv.h b/pngpriv.h
index a71ea1610..3b5770e5e 100644
--- a/pngpriv.h
+++ b/pngpriv.h
@@ -669,6 +669,24 @@
((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
(( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
+/* This returns the number of trailing bits in the last byte of a row, 0 if the
+ * last byte is completely full of pixels. It is, in principle, (pixel_bits x
+ * width) % 8, but that would overflow for large 'width'. The second macro is
+ * the same except that it returns the number of unused bits in the last byte;
+ * (8-TRAILBITS), but 0 when TRAILBITS is 0.
+ *
+ * NOTE: these macros are intended to be self-evidently correct and never
+ * overflow on the assumption that pixel_bits is in the range 0..255. The
+ * arguments are evaluated only once and they can be signed (e.g. as a result of
+ * the integral promotions). The result of the expression always has type
+ * (png_uint_32), however the compiler always knows it is in the range 0..7.
+ */
+#define PNG_TRAILBITS(pixel_bits, width) \
+ (((pixel_bits) * ((width) % (png_uint_32)8)) % 8)
+
+#define PNG_PADBITS(pixel_bits, width) \
+ ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8)
+
/* PNG_OUT_OF_RANGE returns true if value is outside the range
* ideal-delta..ideal+delta. Each argument is evaluated twice.
* "ideal" and "delta" should be constants, normally simple