But what if buf->base is free()d by realloc()? Wouldn't it result in a double-free? Notice the result of the realloc() isn't being assigned to buf->base (buf is const).
And isn't buf->base going to be free()d afterwards anyway? Why bother shrinking it? It might potentially be performing a memcpy().
Also, I'm not familiar with libuv, but it seems flags can potentially specify this is a partial read and more will come later, this doesn't seem to be handled.