]> mj.ucw.cz Git - libucw.git/commitdiff
CRC: Fixed possible integer underflow when called on very small unaligned blocks.
authorPavel Charvat <pchar@ucw.cz>
Mon, 15 Aug 2016 14:07:53 +0000 (16:07 +0200)
committerPavel Charvat <pchar@ucw.cz>
Mon, 15 Aug 2016 14:07:53 +0000 (16:07 +0200)
ucw/crc.c

index 2f818840b3c1d29832eca1e3d6b0ef5ffde3ad53..830d147cde15112588116caa6c781a78200b5370 100644 (file)
--- a/ucw/crc.c
+++ b/ucw/crc.c
@@ -34,6 +34,10 @@ static void crc32_update_by4(crc32_context *ctx, const byte *buf, uint len)
   u32 crc = ctx->state;
   u32 term1, term2, *buf32;
 
+  // Special case
+  if (len < 4)
+    goto small;
+
   // Align start address to a multiple of 4 bytes
   init_bytes = ((uintptr_t) buf) & 3;
   if (init_bytes)
@@ -60,6 +64,7 @@ static void crc32_update_by4(crc32_context *ctx, const byte *buf, uint len)
 
   // Process remaining up to 7 bytes
   buf = (byte *) buf32;
+small:
   while (len--)
     crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
 
@@ -72,6 +77,10 @@ static void crc32_update_by8(crc32_context *ctx, const byte *buf, uint len)
   u32 crc = ctx->state;
   u32 term1, term2, *buf32;
 
+  // Special case
+  if (len < 8)
+    goto small;
+
   // Align start address to a multiple of 8 bytes
   init_bytes = ((uintptr_t) buf) & 7;
   if (init_bytes)
@@ -108,6 +117,7 @@ static void crc32_update_by8(crc32_context *ctx, const byte *buf, uint len)
 
   // Process remaining up to 7 bytes
   buf = (byte *) buf32;
+small:
   while (len--)
     crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);