Skip to content

Commit

Permalink
NUL byte is never sent to user callback (#133)
Browse files Browse the repository at this point in the history
* NUL byte is never sent to user callback

* cstring for memset
  • Loading branch information
charlesnicholson authored Jan 19, 2022
1 parent d89963a commit 8b801d4
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 13 deletions.
10 changes: 5 additions & 5 deletions nanoprintf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1117,8 +1117,7 @@ int npf_vpprintf(npf_putc pc, void *pc_ctx, char const *format, va_list vlist) {
cur += fs_len;
}

NPF_PUTC('\0');
return n - 1;
return n;
}

#undef NPF_PUTC
Expand Down Expand Up @@ -1146,10 +1145,11 @@ int npf_vsnprintf(char *buffer, size_t bufsz, char const *format, va_list vlist)
bufputc_ctx.dst = buffer;
bufputc_ctx.len = bufsz;
bufputc_ctx.cur = 0;
if (buffer && bufsz) { buffer[bufsz - 1] = 0; }

return
npf_vpprintf(buffer ? npf_bufputc : npf_bufputc_nop, &bufputc_ctx, format, vlist);
npf_putc const pc = buffer ? npf_bufputc : npf_bufputc_nop;
int const n = npf_vpprintf(pc, &bufputc_ctx, format, vlist);
pc('\0', &bufputc_ctx);
return n;
}

#endif // NANOPRINTF_IMPLEMENTATION_INCLUDED
Expand Down
14 changes: 14 additions & 0 deletions tests/unit_snprintf.cc
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
#include "unit_nanoprintf.h"
#include "doctest.h"

#include <cstring>
#include <string>
#include <iostream>

TEST_CASE("npf_snprintf") {
char buf[128];

SUBCASE("empty string has null terminator") {
memset(buf, 0xFF, sizeof(buf));
npf_snprintf(buf, sizeof(buf), "");
REQUIRE(buf[0] == '\0');
}

SUBCASE("string has null terminator") {
memset(buf, 0xFF, sizeof(buf));
npf_snprintf(buf, sizeof(buf), "Hello");
REQUIRE(buf[5] == '\0');
REQUIRE(std::string{buf} == "Hello");
}

SUBCASE("returns number of printed characters without null terminator") {
REQUIRE(!npf_snprintf(buf, sizeof(buf), ""));
REQUIRE(npf_snprintf(buf, sizeof(buf), "a") == 1);
Expand Down
14 changes: 6 additions & 8 deletions tests/unit_vpprintf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct Recorder {
}

std::string String() const {
return calls.empty() ? std::string() : std::string(calls.begin(), calls.end() - 1);
return calls.empty() ? std::string() : std::string(calls.begin(), calls.end());
}

std::vector<int> calls;
Expand All @@ -22,20 +22,18 @@ struct Recorder {
TEST_CASE("npf_vpprintf") {
Recorder r;

SUBCASE("empty string only holds null terminator") {
SUBCASE("empty string never calls callback") {
REQUIRE(npf_pprintf(r.PutC, &r, "") == 0);
REQUIRE(r.calls.size() == 1);
REQUIRE(r.calls[0] == '\0');
REQUIRE(r.calls.empty());
}

SUBCASE("single character then null terminator") {
SUBCASE("single character string") {
REQUIRE(npf_pprintf(r.PutC, &r, "A") == 1);
REQUIRE(r.calls.size() == 2);
REQUIRE(r.calls.size() == 1);
REQUIRE(r.calls[0] == 'A');
REQUIRE(r.calls[1] == '\0');
}

SUBCASE("string without format specifiers then null terminator") {
SUBCASE("string without format specifiers") {
std::string const s{"Hello from nanoprintf!"};
REQUIRE(npf_pprintf(r.PutC, &r, s.c_str()) == (int)s.size());
REQUIRE(s == r.String());
Expand Down

0 comments on commit 8b801d4

Please sign in to comment.