8213622: Windows VS2013 build failure - "'snprintf': identifier not found" jdk-12+20
authorjcbeyler
Wed, 14 Nov 2018 12:25:15 -0800
changeset 52561 40098289d580
parent 52560 f5011100c920
child 52562 3a9384c12260
8213622: Windows VS2013 build failure - "'snprintf': identifier not found" Summary: Replace snprintf with strlen and memcpy Reviewed-by: dholmes, mvala, kbarrett
test/hotspot/jtreg/vmTestbase/nsk/share/jni/ExceptionCheckingJniEnv.cpp
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jni/ExceptionCheckingJniEnv.cpp	Wed Nov 14 11:42:40 2018 -0800
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jni/ExceptionCheckingJniEnv.cpp	Wed Nov 14 12:25:15 2018 -0800
@@ -23,6 +23,7 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
 
 #include "ExceptionCheckingJniEnv.hpp"
 
@@ -48,12 +49,21 @@
   }
 
   void ProcessReturnError() {
-    int len = snprintf(NULL, 0, "%s : %s", _base_msg, _return_error) + 1;
+    // This is error prone, but:
+    //   - Seems like we cannot use std::string (due to windows/solaris not
+    //   building when used, seemingly due to exception libraries not linking).
+    //   - Seems like we cannot use sprintf due to VS2013 (JDK-8213622).
+    //
+    //   We are aiming to do:
+    //     snprintf(full_message, len, "%s : %s", _base_msg, _return_error);
+    //   but will use strlen + memcpy instead.
+    size_t base_len = strlen(_base_msg);
+    const char* between_msg = " : ";
+    size_t between_len = strlen(between_msg);
+    size_t return_len = strlen(_return_error);
 
-    if (len <= 0) {
-      _env->HandleError(_return_error);
-      return;
-    }
+    // +1 for the '\0'
+    size_t len = base_len + between_len + return_len + 1;
 
     char* full_message = (char*) malloc(len);
     if (full_message == NULL) {
@@ -61,7 +71,18 @@
       return;
     }
 
-    snprintf(full_message, len, "%s : %s", _base_msg, _return_error);
+    // Now we construct the string using memcpy to not use sprintf/std::string
+    // instead of:
+    //     snprintf(full_message, len, "%s : %s", _base_msg, _return_error);
+    memcpy(full_message, _base_msg, base_len);
+    memcpy(full_message + base_len, between_msg, between_len);
+    memcpy(full_message + base_len + between_len, _return_error, return_len);
+    full_message[len - 1] = '\0';
+
+    // -1 due to the '\0' not counted by strlen but is counted for the allocation.
+    if (strlen(full_message) != len - 1) {
+      _env->GetJNIEnv()->FatalError("Length of message is not what was expected");
+    }
 
     _env->HandleError(full_message);
     free(full_message);