Skip to content

print empty bin/ext in msgpack_object_print_buffer - #1209

Open
trestoncuzzort wants to merge 1 commit into
msgpack:c_masterfrom
trestoncuzzort:print-buffer-empty-bin
Open

trestoncuzzort wants to merge 1 commit into
msgpack:c_masterfrom
trestoncuzzort:print-buffer-empty-bin

Conversation

@trestoncuzzort

Copy link
Copy Markdown

msgpack_object_print_buffer returns 0 for a bin or ext object that has no bytes, and for every array or map that holds one. msgpack_object_bin_print_buffer returns the number of characters it wrote, which is 0 for such an object, and MSGPACK_CHECKED_CALL takes 0 as a failure. The buffer is left with the text up to the opening quote:

object msgpack_object_print msgpack_object_print_buffer, before after
c4 00 (bin 8, no bytes) "" ", returns 0 "", returns 2
c7 00 01 (ext 8, type 1, no bytes) (ext: 1)"" (ext: 1)", returns 0 (ext: 1)"", returns 10
94 01 c4 00 c7 00 01 03 [1, "", (ext: 1)"", 3] [1, ", returns 0 [1, "", (ext: 1)"", 3], returns 22

A caller that prints the buffer without looking at the result, as example/user_buffer_unpack.c does, shows the cut-off text.

#942 fixed the same thing for empty strings by skipping the call when the size is 0. This change does that on the bin and ext branches. Objects that have bytes print as before, and the truncation behaviour from #1196 is unchanged.

Tests. The three new tests (empty bin, empty ext, an unpacked array that holds both) fail on the current tree and pass with the change. I ran the build and test commands of ci/build_cmake.sh (ASan and UBSan, -Werror) with gcc 13.3 and with clang 18.1.8, each with signed and with unsigned char: 113 test cases pass before the change and 116 after it. I did not run the 32-bit jobs, the valgrind step, macOS or Windows.

I also checked the two branches with the CBMC model checker (6.11.0): for a bin or ext object of zero to two bytes of any value, and every buffer size from 0 to 24, the result, the text, the terminator and the bytes after buffer_size are what msgpack_object_print writes. The current code fails that for objects without bytes. CBMC has no usable snprintf, so the model uses a small stand-in; the same harness, run natively with glibc over all 422,720,025 inputs, agrees: the current code fails for the 3,184 inputs with an object without bytes and enough room, and the changed code for none. The harness and the results are in https://github.com/trestoncuzzort/dawnr/tree/394639809ba9672b4a290aa4b29f9c91008384dd/t/native_fixtures/msgpack-c-print-buffer-empty-bin.

msgpack_object_bin_print_buffer returns the number of characters it
wrote, which is 0 for a bin or ext object with no bytes, and
MSGPACK_CHECKED_CALL takes 0 as a failure. msgpack_object_print_buffer
then returned 0 with the output cut off after the opening quote, also
for an array or a map that holds such an object.

Skip the call when the size is 0, as the str branch does.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant