On 15/06/2021 08.43, Justin He wrote: > Hi Rasmus > >> -----Original Message----- >> From: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx> >> Why the !buf check? The only way we can have that is the snprintf(NULL, >> 0, ...) case of asking how much space we'd need to malloc, right? In >> which case end would be NULL+0 == NULL, so buf >= end automatically, >> regardless of how much have been "printed" before %pD. > > My original purpose is to avoid any memory copy/move for kvasprintf-> > vsnprintf(NULL, 0,...). But as you said, this can be folded into the case > buf >= end. > Do you think whether following case should be forbidden?: > vsnprintf(NULL, 8,...). That is an obvious caller bug. The caller tells vsnprintf "here's a buffer of size 8 at address 0x0". And checking buf for NULL in the guts of %pD would anyway be completely pointless as it would crash for a fmt of "x%pD" or basically anything at all before %pD because those specifiers (or literal parts) would cause a write to buf - and if that somehow survived, the buf %pD would be given would now be (void*)1L. >> Now you're passing p to string_truncate or string_nocheck, while p >> points somewhere into buf itself. I can't convince myself that would be >> safe. At the very least, it deserves a couple of comments. > > When code goes here, the buffer space must be as follows: > |.........|.........| > buf p end > > So string_nocheck is safe because essential it would byte-to-byte copy p to buf. > > But I agree comments are needed here. Yes, because no matter how string_nocheck happens to be implemented today, some day somebody might throw in a memcpy() or do something else that means overlapping "buf" and "s" arguments are suddenly broken in some configurations or arches. Rasmus