]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
msnprintf: return number of printed characters excluding null byte
authorDaniel Stenberg <daniel@haxx.se>
Wed, 7 Jul 2021 12:51:17 +0000 (14:51 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 8 Jul 2021 08:05:39 +0000 (10:05 +0200)
... even when the output is "capped" by the maximum length argument.

Clarified in the docs.

Closes #7361

docs/libcurl/curl_mprintf.3
lib/mprintf.c
lib/sendf.c
tests/libtest/lib557.c
tests/unit/unit1398.c
tests/unit/unit1652.c

index 99f5236b896d79d437a7e16c86ff982139273d7a..e0a7af79d134b8ad1f15a09e06fbe5cf6adc1619 100644 (file)
@@ -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) "
index 5292026861583e7fa2e40730f5ae92e437c6d0cb..7a1aec570e5ad6247cedc6a2cfe57884a858aeca 100644 (file)
@@ -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;
   }
index d56399b773dec3bf6d6f205ffd05084010fce7f8..14ca84bfe5bf5dd634f13ebe7bb725c40a0dfe47 100644 (file)
@@ -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);
index 00fbca38c17052ab9317ea3cda43bf30c44bfd07..b6b8bec1fb278c28cc71803aa80b5d9c75c9597f 100644 (file)
@@ -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
index 43e1f47a500a9c38b37280e6dc2888250939c3a6..e73ce24b0cf851b420ba55a27a261c79f4c8e9ab 100644 (file)
@@ -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
index 26f11e4838894ec3dc40e28334a19b0a2cc1e460..56dad0c3419fdeff2b126eafb5444d3cf64805ec 100644 (file)
@@ -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");