Allocate a fixed length buffer for the header and read the header, inspect the length field and allocate a second buffer with this length and finally read the variable length part into this second buffer. Maybe check that there is no trailing data. This is what you would probably do anyway if the variable length part could be way larger then 64 kiB and just blindly allocating for the maximum length is not an option.
Right. Now you've got significantly more code (and even more chances of getting it wrong), more allocations, and you can still fail to correctly handle read(2) not completely filling a buffer and leaking data. Although most likely less than in heartbleed.
How did we end up here? My initial point was that zeroing memory does not prevent leaks in the general case and we both agree on that. I never claimed OpenSSL should or should not have done something differently.