diff --git a/src/kex.c b/src/kex.c index 2e86b656..ed00c6a3 100644 --- a/src/kex.c +++ b/src/kex.c @@ -3286,24 +3286,40 @@ kex_agree_instr(unsigned char *haystack, unsigned long haystack_len, const unsigned char *needle, unsigned long needle_len) { unsigned char *s; + unsigned char *end_haystack; + unsigned long left; - /* Haystack too short to bother trying */ - if(haystack_len < needle_len) { + if(haystack == NULL || needle == NULL) { return NULL; } + /* Haystack too short to bother trying */ + if(haystack_len < needle_len || needle_len == 0) { + return NULL; + } + + s = haystack; + end_haystack = &haystack[haystack_len]; + left = end_haystack - s; + /* Needle at start of haystack */ if((strncmp((char *) haystack, (char *) needle, needle_len) == 0) && (needle_len == haystack_len || haystack[needle_len] == ',')) { return haystack; } - s = haystack; /* Search until we run out of comas or we run out of haystack, whichever comes first */ - while((s = (unsigned char *) strchr((char *) s, ',')) - && ((haystack_len - (s - haystack)) > needle_len)) { - s++; + while((s = (unsigned char *) memchr((char *) s, ',', left))) { + /* Advance buffer past coma if we can */ + left = end_haystack - s; + if((left >= 1) && (left <= haystack_len) && (left > needle_len)) { + s++; + } + else { + return NULL; + } + /* Needle at X position */ if((strncmp((char *) s, (char *) needle, needle_len) == 0) && (((s - haystack) + needle_len) == haystack_len