msnprintf: return number of printed characters excluding null byte
... even when the output is "capped" by the maximum length argument. Clarified in the docs. Closes #7361
This commit is contained in:
Родитель
e7416cfd2b
Коммит
9053dbbf62
|
@ -246,8 +246,8 @@ not use them in new programs or projects.
|
|||
The \fBcurl_maprintf\fP and \fBcurl_mvaprintf\fP functions return a pointer to
|
||||
a newly allocated string, or NULL if it failed.
|
||||
|
||||
All other functions return the number of characters they actually
|
||||
outputted. Note that this differs from how the POSIX versions of these
|
||||
functions work.
|
||||
All other functions return the number of characters actually printed
|
||||
(excluding the null byte used to end output to strings). Note that this
|
||||
sometimes differ from how the POSIX versions of these functions work.
|
||||
.SH "SEE ALSO"
|
||||
.BR printf "(3), " sprintf "(3), " fprintf "(3), " vprintf "(3) "
|
||||
|
|
|
@ -1017,9 +1017,11 @@ int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
|
|||
retcode = dprintf_formatf(&info, addbyter, format, ap_save);
|
||||
if((retcode != -1) && info.max) {
|
||||
/* we terminate this with a zero byte */
|
||||
if(info.max == info.length)
|
||||
if(info.max == info.length) {
|
||||
/* we're at maximum, scrap the last letter */
|
||||
info.buffer[-1] = 0;
|
||||
retcode--; /* don't count the nul byte */
|
||||
}
|
||||
else
|
||||
info.buffer[0] = 0;
|
||||
}
|
||||
|
|
|
@ -246,8 +246,7 @@ void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
|
|||
size_t len;
|
||||
char buffer[MAXINFO + 2];
|
||||
va_start(ap, fmt);
|
||||
(void)mvsnprintf(buffer, MAXINFO, fmt, ap);
|
||||
len = strlen(buffer);
|
||||
len = mvsnprintf(buffer, MAXINFO, fmt, ap);
|
||||
va_end(ap);
|
||||
buffer[len++] = '\n';
|
||||
buffer[len] = '\0';
|
||||
|
@ -267,8 +266,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
|
|||
size_t len;
|
||||
char error[CURL_ERROR_SIZE + 2];
|
||||
va_start(ap, fmt);
|
||||
(void)mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
||||
len = strlen(error);
|
||||
len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
||||
|
||||
if(data->set.errorbuffer && !data->state.errorbuf) {
|
||||
strcpy(data->set.errorbuffer, error);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@ -1541,8 +1541,9 @@ static int test_weird_arguments(void)
|
|||
buf[0] = 0;
|
||||
rc = curl_msnprintf(buf, sizeof(buf), "%d, %.*1$d", 500, 1);
|
||||
|
||||
if(rc != 256) {
|
||||
printf("curl_mprintf() returned %d and not 256!\n", rc);
|
||||
if(rc != sizeof(buf) - 1) {
|
||||
printf("curl_mprintf() returned %d and not %d!\n", rc,
|
||||
sizeof(buf) - 1);
|
||||
errors++;
|
||||
}
|
||||
|
||||
|
@ -1669,6 +1670,36 @@ static int test_float_formatting(void)
|
|||
}
|
||||
/* !checksrc! enable LONGLINE */
|
||||
|
||||
static int test_return_codes(void)
|
||||
{
|
||||
char buf[128];
|
||||
int rc;
|
||||
|
||||
rc = curl_msnprintf(buf, 100, "%d", 9999);
|
||||
if(rc != 4)
|
||||
return 1;
|
||||
|
||||
rc = curl_msnprintf(buf, 100, "%d", 99999);
|
||||
if(rc != 5)
|
||||
return 1;
|
||||
|
||||
/* returns the length excluding the nul byte */
|
||||
rc = curl_msnprintf(buf, 5, "%d", 99999);
|
||||
if(rc != 4)
|
||||
return 1;
|
||||
|
||||
/* returns the length excluding the nul byte */
|
||||
rc = curl_msnprintf(buf, 5, "%s", "helloooooooo");
|
||||
if(rc != 4)
|
||||
return 1;
|
||||
|
||||
/* returns the length excluding the nul byte */
|
||||
rc = curl_msnprintf(buf, 6, "%s", "helloooooooo");
|
||||
if(rc != 5)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int test(char *URL)
|
||||
{
|
||||
int errors = 0;
|
||||
|
@ -1702,6 +1733,8 @@ int test(char *URL)
|
|||
|
||||
errors += test_float_formatting();
|
||||
|
||||
errors += test_return_codes();
|
||||
|
||||
if(errors)
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
else
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@ -64,27 +64,27 @@ fail_unless(!strcmp(output, "012"), "wrong output");
|
|||
|
||||
/* negative width */
|
||||
rc = curl_msnprintf(output, 8, "%-8s", str);
|
||||
fail_unless(rc == 8, "return code should be 8");
|
||||
fail_unless(rc == 7, "return code should be 7");
|
||||
fail_unless(!strcmp(output, "bug "), "wrong output");
|
||||
|
||||
/* larger width that string length */
|
||||
rc = curl_msnprintf(output, 8, "%8s", str);
|
||||
fail_unless(rc == 8, "return code should be 8");
|
||||
fail_unless(rc == 7, "return code should be 7");
|
||||
fail_unless(!strcmp(output, " bu"), "wrong output");
|
||||
|
||||
/* output a number in a limited output */
|
||||
rc = curl_msnprintf(output, 4, "%d", 10240);
|
||||
fail_unless(rc == 4, "return code should be 4");
|
||||
fail_unless(rc == 3, "return code should be 3");
|
||||
fail_unless(!strcmp(output, "102"), "wrong output");
|
||||
|
||||
/* padded strings */
|
||||
rc = curl_msnprintf(output, 16, "%8s%8s", str, str);
|
||||
fail_unless(rc == 16, "return code should be 16");
|
||||
fail_unless(rc == 15, "return code should be 15");
|
||||
fail_unless(!strcmp(output, " bug bu"), "wrong output");
|
||||
|
||||
/* padded numbers */
|
||||
rc = curl_msnprintf(output, 16, "%8d%8d", 1234, 5678);
|
||||
fail_unless(rc == 16, "return code should be 16");
|
||||
fail_unless(rc == 15, "return code should be 15");
|
||||
fail_unless(!strcmp(output, " 1234 567"), "wrong output");
|
||||
|
||||
UNITTEST_STOP
|
||||
|
|
|
@ -108,7 +108,7 @@ fail_unless(verify(result, "(nil)") == 0, "Passing NULL as string");
|
|||
|
||||
/* A string just long enough to not be truncated */
|
||||
memset(input, '\0', sizeof(input));
|
||||
memset(input, 'A', 2048);
|
||||
memset(input, 'A', 2047);
|
||||
Curl_infof(data, "%s", input);
|
||||
fail_unless(strlen(result) == 2048, "No truncation of infof input");
|
||||
fail_unless(verify(result, input) == 0, "No truncation of infof input");
|
||||
|
|
Загрузка…
Ссылка в новой задаче