Skip to content

Commit

Permalink
fix(printf): zero precision and zero value hash problem
Browse files Browse the repository at this point in the history
Fixes #26
  • Loading branch information
mpaland committed Sep 14, 2018
1 parent 6dae168 commit 7075d31
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
16 changes: 13 additions & 3 deletions printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t ma

// handle hash
if (flags & FLAGS_HASH) {
if (((len == prec) || (len == width)) && (len > 0U)) {
if (len && ((len == prec) || (len == width))) {
len--;
if ((base == 16U) && (len > 0U)) {
if (len && (base == 16U)) {
len--;
}
}
Expand All @@ -181,7 +181,7 @@ static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t ma
}

// handle sign
if ((len == width) && (negative || (flags & FLAGS_PLUS) || (flags & FLAGS_SPACE))) {
if (len && (len == width) && (negative || (flags & FLAGS_PLUS) || (flags & FLAGS_SPACE))) {
len--;
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
Expand Down Expand Up @@ -225,6 +225,11 @@ static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxl
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;

// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}

// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
Expand All @@ -245,6 +250,11 @@ static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;

// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}

// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
Expand Down
14 changes: 14 additions & 0 deletions test/test_suite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ TEST_CASE("+ flag", "[]" ) {

test::sprintf(buffer, "%+c", 'x');
REQUIRE(!strcmp(buffer, "x"));

test::sprintf(buffer, "%+.0d", 0);
REQUIRE(!strcmp(buffer, "+"));
}


Expand Down Expand Up @@ -344,6 +347,14 @@ TEST_CASE("- flag", "[]" ) {
}


TEST_CASE("# flag", "[]" ) {
char buffer[100];

test::sprintf(buffer, "%#.0x", 0);
REQUIRE(!strcmp(buffer, ""));
}


TEST_CASE("specifier", "[]" ) {
char buffer[100];

Expand Down Expand Up @@ -1232,6 +1243,9 @@ TEST_CASE("misc", "[]" ) {
test::sprintf(buffer, "%.3s", "foobar");
REQUIRE(!strcmp(buffer, "foo"));

test::sprintf(buffer, "% .0d", 0);
REQUIRE(!strcmp(buffer, " "));

test::sprintf(buffer, "%10.5d", 4);
REQUIRE(!strcmp(buffer, " 00004"));

Expand Down

1 comment on commit 7075d31

@eyalroz
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This "fix" may have broken (at least) the behavior of the alternative mode for %o causing - apparently - issue #109 .

Also, and more generally - it doesn't make sense to drop a flag when that flag was specified. It means you will be misleading the reader of the code for the rest of the function.

Please sign in to comment.