[Groonga-commit] groonga/groonga at f05bcb1 [master] grn_text_vprintf windows: fix a bug auto buffer expansion doesn't work

Back to archive index
Kouhei Sutou null+****@clear*****
Thu May 9 08:33:06 JST 2019


Kouhei Sutou	2019-05-09 08:33:06 +0900 (Thu, 09 May 2019)

  Revision: f05bcb1f7a8c9d3ca764cfd81ef5d3cd324b758c
  https://github.com/groonga/groonga/commit/f05bcb1f7a8c9d3ca764cfd81ef5d3cd324b758c

  Message:
    grn_text_vprintf windows: fix a bug auto buffer expansion doesn't work
    
    vsnprintf() with not enough buffer returns -1 not the number of
    written characters. It's not different with the document:
    
    https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vsnprintf-vsnprintf-vsnprintf-l-vsnwprintf-vsnwprintf-l?view=vs-2019
    
    > If the buffer size specified by count is not sufficiently large to
    > contain the output specified by format and argptr, the return value
    > of vsnprintf is the number of characters that would be written, not
    > counting the null character

  Modified files:
    lib/str.c

  Modified: lib/str.c (+24 -29)
===================================================================
--- lib/str.c    2019-05-08 18:00:54 +0900 (b4fd0963d)
+++ lib/str.c    2019-05-09 08:33:06 +0900 (0c369f9f7)
@@ -2599,49 +2599,44 @@ grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args)
                              format, copied_args);
     va_end(copied_args);
 
-    if (0 <= written_size && written_size < rest_size) {
+    if (written_size < rest_size) {
       is_written = GRN_TRUE;
     }
   }
 
   if (!is_written) {
 #ifdef WIN32
-# define N_NEW_SIZES 3
-    int i;
-    int new_sizes[N_NEW_SIZES];
+    grn_rc rc;
+    int required_size;
 
-    new_sizes[0] = GRN_BULK_REST(bulk) + strlen(format) * 2;
-    new_sizes[1] = new_sizes[0] + 4096;
-    new_sizes[2] = new_sizes[0] + 65536;
+    va_copy(copied_args, args);
+    required_size = vsnprintf(NULL, 0, format, copied_args);
+    va_end(copied_args);
 
-    for (i = 0; i < N_NEW_SIZES; i++) {
+    if (required_size < 0) {
+      return GRN_INVALID_ARGUMENT;
+    }
+    required_size++; /* for terminate '\0'. */
+    rc = grn_bulk_reserve(ctx, bulk, required_size);
+    if (rc) {
+      return rc;
+    }
+    va_copy(copied_args, args);
+    written_size = vsnprintf(GRN_BULK_CURR(bulk), required_size,
+                             format, copied_args);
+    va_end(copied_args);
+#else /* WIN32 */
+    if (written_size >= 0) {
       grn_rc rc;
-      int new_size = new_sizes[i];
-      va_list copied_args;
+      int required_size = written_size + 1; /* "+ 1" for terminate '\0'. */
 
-      rc = grn_bulk_reserve(ctx, bulk, GRN_BULK_VSIZE(bulk) + new_size);
+      rc = grn_bulk_reserve(ctx, bulk, required_size);
       if (rc) {
         return rc;
       }
-      va_copy(copied_args, args);
-      written_size = vsnprintf(GRN_BULK_CURR(bulk), new_size,
-                               format, copied_args);
-      va_end(copied_args);
-      if (written_size != -1) {
-        break;
-      }
+      written_size = vsnprintf(GRN_BULK_CURR(bulk), required_size,
+                               format, args);
     }
-# undef N_NEW_SIZES
-#else /* WIN32 */
-    grn_rc rc;
-    int required_size = written_size + 1; /* "+ 1" for terminate '\0'. */
-
-    rc = grn_bulk_reserve(ctx, bulk, GRN_BULK_VSIZE(bulk) + required_size);
-    if (rc) {
-      return rc;
-    }
-    written_size = vsnprintf(GRN_BULK_CURR(bulk), required_size,
-                             format, args);
 #endif /* WIN32 */
   }
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20190509/5af4eff7/attachment-0001.html>


More information about the Groonga-commit mailing list
Back to archive index