A confusing problem of `snprintf()` without adding `'0'`

59 views Asked by At

I came across a confusing problem involving snprintf() when using qt5.6 with (mingw 5.3.0 32bit) on win10.

My code is as follows:

char *my3DesCBC_Decode_default(char *in_24char_CipherTxt,
                               char *out_32char_PlainTxt) {
  int xLen = 24; // default:24;
  int len001 = 0;
  unsigned char *res_PlainTxt;
  unsigned char *res_decode_Base64;

  base64_de((unsigned char *)in_24char_CipherTxt, &res_decode_Base64, &xLen);

  if (des_decode(DES3_CBC, pmingKey16_default, pmingKeyLen_default,
                 pmingVI008_default, res_decode_Base64, &res_PlainTxt,
                 &xLen) == RESULT_OK) {

    xLen = xLen > 30 ? 30 : xLen; // `xLen`: true length of decrypted string
    snprintf(out_32char_PlainTxt, xLen + 0, "%s", res_PlainTxt); // problem from this line
    len001 = strlen(out_32char_PlainTxt);
    printf("3DES CBC DECODE:%s ;Len=%d,%d\n", out_32char_PlainTxt, xLen,
           len001);
  }
}

The line snprintf(out_32char_PlainTxt, xLen + 0, "%s", res_PlainTxt); works. However, according to the document, xLen + 0 here should be xLen + 1. When I use xLen + 1, it raised an error, to make it run again, I have to write

snprintf(out_32char_CipherTxt,xLen+1,"%s",res_encode_Base64);
\*(out_32char_CipherTxt + xLen) = '\0';

More specifically, xLen + 1 should be right because there needs another bit to store the eof '\0' that is added by snprintf() automatically. I wonder why I have to add '\0' by myself ? Is there any trap of snprintf() on different platforms ?

1

There are 1 answers

0
Luuk On

I am not a C++ programmer, but may I suggest to create a mre ?:

#include <stdio.h>
int main ()
{
  char input [25] = "abcdefghijklmnopqrstuvwx";
  char output [100] ;
  printf("strlen: %d\n", (int)sizeof(input));

  printf("snprintf: %d\n", snprintf( output, 10, input));
  printf("input: %s\n", input);
  printf("output: %s\n", output);

  return 0;
}

output:

strlen: 25
snprintf: 24
input: abcdefghijklmnopqrstuvwx
output: abcdefghi

When second parameter is 10, the results will be 9 character long (abcdefghi).

(My) conclusion:

When you have a problem using:

snprintf(out_32char_PlainTxt, xLen + 0, "%s", res_PlainTxt); // problem from this line

and the problem is that the result is 1 character too small, then you can use xLen + 1.

But this seems pretty standard C++, (and I repeat myself:) I am not a C++ programmer!