File cyrus-imapd_urlfetch_range_handling.patch of Package cyrus-imapd.3194

Index: cyrus-imapd-2.3.18/imap/index.c
===================================================================
--- cyrus-imapd-2.3.18.orig/imap/index.c
+++ cyrus-imapd-2.3.18/imap/index.c
@@ -2774,8 +2774,10 @@ int index_urlfetch(struct mailbox *mailb
     cacherecord crec;
     const char *cachestr;
     int fetchmime = 0;
-    unsigned size, offset = 0, skip = 0;
-    int n, r = 0;
+    size_t size, offset = 0;
+	unsigned skip = 0;
+	unsigned long n;
+    int r = 0;
 
     if (outsize) *outsize = 0;
 
@@ -2863,26 +2865,42 @@ int index_urlfetch(struct mailbox *mailb
 	    goto done;
 	}
 
-	offset = CACHE_ITEM_BIT32(cachestr);
-	size = CACHE_ITEM_BIT32(cachestr + CACHE_ITEM_SIZE_SKIP);
+	size_t section_offset = CACHE_ITEM_BIT32(cachestr);
+	size_t section_size = CACHE_ITEM_BIT32(cachestr + CACHE_ITEM_SIZE_SKIP);
+
+	if (section_offset + section_size < section_offset
+		|| section_offset + section_size > size) {
+		r = IMAP_INTERNAL;
+		goto done;
+	}
+
+	offset += section_offset;
+	size = section_size;
     }
 
-    /* Handle PARTIAL request */
-    offset += start_octet;
-    if (octet_count) size = octet_count;
+	/* Handle PARTIAL request */
+    n = octet_count ? octet_count : size;
 
     /* Sanity check the requested size */
-    if (size && (offset + size > msg_size))
-	n = msg_size - offset;
-    else
-	n = size;
+    if (start_octet > size) {
+        start_octet = size;
+        n = 0;
+    }
+    else if (start_octet + n < start_octet || start_octet + n > size) {
+		if (size - start_octet >= 0){
+			n = size - start_octet;
+		}
+		else {
+			n = 0;
+		}
+    }
 
     if (outsize)
 	*outsize = n;
     else
-	prot_printf(pout, "{%u}\r\n", n);
+	prot_printf(pout, "{%lu}\r\n", n);
 
-    prot_write(pout, msg_base + offset, n);
+    if (n) prot_write(pout, msg_base + offset, n);
 
   done:
     /* Close the message file */
openSUSE Build Service is sponsored by