If the input hostname is "[", hlen will underflow to max of size_t when
it is subtracted with 2.
hostname[hlen] will then cause a warning by ubsanitizer:
runtime error: addition of unsigned offset to 0x<snip> overflowed to
0x<snip>
I think that in practice, the generated code will work, and the output
of hostname[hlen] will be the first character "[".
This can be demonstrated by the following program (tested in both clang
and gcc, with -O3)
int main() {
char* hostname=strdup("[");
size_t hlen = strlen(hostname);
hlen-=2;
hostname++;
printf("character is %d\n",+hostname[hlen]);
free(hostname-1);
}
I found this through fuzzing, and even if it seems harmless, the proper
thing is to return early with an error.
Closes #4389
if(hostname[0] == '[') {
char dest[16]; /* fits a binary IPv6 address */
const char *l = "0123456789abcdefABCDEF:.";
+ if(hlen < 5) /* '[::1]' is the shortest possible valid string */
+ return CURLUE_MALFORMED_INPUT;
hostname++;
hlen -= 2;