(Minor bug, we have a simple enough workaround but wanted to at least document the requirement)
We use KBTS_MALLOC to ensure allocations go through our engine's allocator, and I've discovered that kb has issues if we return nullptr on a malloc(0) situation. Namely, kbts_LoadFont sizes its scratch buffer as the summed length of GSUB GPOS and GDEF, and in cases where that sums to zero bytes (i.e. Arial Narrow), the scratch buffer size is zero bytes. If the allocator returns nullptr for a zero-byte allocation (which is legit per the C rules, at least[1]) then when kbts_PlaceBlob is called with a nullptr ScratchMemory then we hit the KBTS_LOAD_FONT_ERROR_OUT_OF_MEMORY case.
So for now at least I'm clamping KBTS_MALLOC to a minimum of 1 byte to work around this issue, which should be fine but again I just wanted to call out this requirement explicitly.
[1] "If the size of the space requested is 0, the behavior is implementation-defined: either a null pointer shall be returned, or the behavior shall be as if the size were some non-zero value, except that the behavior is undefined if the returned pointer is used to access an object."
This is not good. You should be able to just return 0.
I added a check for this in
PlaceBlob, though others might pop up yet. https://github.com/JimmyLefevre/kb/commit/826ec09239897183a7dab2a364f72486f099509d