int32 len;
int32 off;
+ /*
+ * A match tag is at least 2 bytes; if the length nibble is
+ * 0x0f the tag is 3 bytes (extended length). Verify we have
+ * enough source data before reading them.
+ */
+ if (unlikely(sp + 2 > srcend))
+ return -1;
+
len = (sp[0] & 0x0f) + 3;
off = ((sp[0] & 0xf0) << 4) | sp[1];
sp += 2;
if (len == 18)
+ {
+ if (unlikely(sp >= srcend))
+ return -1;
len += *sp++;
+ }
/*
- * Check for corrupt data: if we fell off the end of the
- * source, or if we obtained off = 0, or if off is more than
- * the distance back to the buffer start, we have problems.
- * (We must check for off = 0, else we risk an infinite loop
- * below in the face of corrupt data. Likewise, the upper
- * limit on off prevents accessing outside the buffer
- * boundaries.)
+ * Check for corrupt data: if we obtained off = 0, or if off
+ * is more than the distance back to the buffer start, we have
+ * problems. (We must check for off = 0, else we risk an
+ * infinite loop below in the face of corrupt data. Likewise,
+ * the upper limit on off prevents accessing outside the
+ * buffer boundaries.)
*/
- if (unlikely(sp > srcend || off == 0 ||
+ if (unlikely(off == 0 ||
off > (dp - (unsigned char *) dest)))
return -1;