mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone
Blob Blame History Raw
From 5c5cc8b7bc2588c04dd0d0472b466f978f8ac55c Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 6 Feb 2020 10:17:35 +0000
Subject: [PATCH] ocaml: Use caml_alloc_initialized_string instead of memcpy.

See this commit in libguestfs-common:
https://github.com/libguestfs/libguestfs-common/commit/398dc56a6cb5d6d01506338fa94ef580e668d5e9

(cherry picked from commit 9f3148c791a970b7d6adf249e949a1b7e0b4b0c1)
---
 generator/OCaml.ml  | 10 ++++------
 m4/guestfs-ocaml.m4 | 18 ++++++++++++++++++
 ocaml/guestfs-c.c   |  3 +--
 ocaml/guestfs-c.h   | 18 ++++++++++++++++++
 4 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/generator/OCaml.ml b/generator/OCaml.ml
index bd4f73b85..1b6970f6d 100644
--- a/generator/OCaml.ml
+++ b/generator/OCaml.ml
@@ -504,12 +504,11 @@ copy_table (char * const * argv)
            | name, FString ->
                pr "  v = caml_copy_string (%s->%s);\n" typ name
            | name, FBuffer ->
-               pr "  v = caml_alloc_string (%s->%s_len);\n" typ name;
-               pr "  memcpy (String_val (v), %s->%s, %s->%s_len);\n"
+               pr "  v = caml_alloc_initialized_string (%s->%s_len, %s->%s);\n"
                  typ name typ name
            | name, FUUID ->
-               pr "  v = caml_alloc_string (32);\n";
-               pr "  memcpy (String_val (v), %s->%s, 32);\n" typ name
+               pr "  v = caml_alloc_initialized_string (32, %s->%s);\n"
+                 typ name
            | name, (FBytes|FInt64|FUInt64) ->
                pr "  v = caml_copy_int64 (%s->%s);\n" typ name
            | name, (FInt32|FUInt32) ->
@@ -757,8 +756,7 @@ copy_table (char * const * argv)
            pr "  for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
            pr "  free (r);\n";
        | RBufferOut _ ->
-           pr "  rv = caml_alloc_string (size);\n";
-           pr "  memcpy (String_val (rv), r, size);\n";
+           pr "  rv = caml_alloc_initialized_string (size, r);\n";
            pr "  free (r);\n"
       );
 
diff --git a/m4/guestfs-ocaml.m4 b/m4/guestfs-ocaml.m4
index 3c504ce7e..90658e8c5 100644
--- a/m4/guestfs-ocaml.m4
+++ b/m4/guestfs-ocaml.m4
@@ -221,6 +221,24 @@ AS_IF([test "x$have_Hivex_OPEN_UNSAFE" = "xno"],[
 ])
 AC_SUBST([HIVEX_OPEN_UNSAFE_FLAG])
 
+dnl Check if OCaml has caml_alloc_initialized_string (added 2017).
+AS_IF([test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && \
+       test "x$enable_ocaml" = "xyes"],[
+    AC_MSG_CHECKING([for caml_alloc_initialized_string])
+    cat >conftest.c <<'EOF'
+#include <caml/alloc.h>
+int main () { char *p = (void *) caml_alloc_initialized_string; return 0; }
+EOF
+    AS_IF([$OCAMLC conftest.c >&AS_MESSAGE_LOG_FD 2>&1],[
+        AC_MSG_RESULT([yes])
+        AC_DEFINE([HAVE_CAML_ALLOC_INITIALIZED_STRING],[1],
+                  [caml_alloc_initialized_string found at compile time.])
+    ],[
+        AC_MSG_RESULT([no])
+    ])
+    rm -f conftest.c conftest.o
+])
+
 dnl Flags we want to pass to every OCaml compiler call.
 OCAML_WARN_ERROR="-warn-error CDEFLMPSUVYZX+52-3"
 AC_SUBST([OCAML_WARN_ERROR])
diff --git a/ocaml/guestfs-c.c b/ocaml/guestfs-c.c
index 3b5fb198f..18d7dd978 100644
--- a/ocaml/guestfs-c.c
+++ b/ocaml/guestfs-c.c
@@ -360,8 +360,7 @@ event_callback_wrapper_locked (guestfs_h *g,
 
   ehv = Val_int (event_handle);
 
-  bufv = caml_alloc_string (buf_len);
-  memcpy (String_val (bufv), buf, buf_len);
+  bufv = caml_alloc_initialized_string (buf_len, buf);
 
   arrayv = caml_alloc (array_len, 0);
   for (i = 0; i < array_len; ++i) {
diff --git a/ocaml/guestfs-c.h b/ocaml/guestfs-c.h
index f05dbd8e7..93ad3e2bf 100644
--- a/ocaml/guestfs-c.h
+++ b/ocaml/guestfs-c.h
@@ -19,6 +19,24 @@
 #ifndef GUESTFS_OCAML_C_H
 #define GUESTFS_OCAML_C_H
 
+#include "config.h"
+
+#include <caml/alloc.h>
+#include <caml/mlvalues.h>
+
+/* Replacement if caml_alloc_initialized_string is missing, added
+ * to OCaml runtime in 2017.
+ */
+#ifndef HAVE_CAML_ALLOC_INITIALIZED_STRING
+static inline value
+caml_alloc_initialized_string (mlsize_t len, const char *p)
+{
+  value sv = caml_alloc_string (len);
+  memcpy ((char *) String_val (sv), p, len);
+  return sv;
+}
+#endif
+
 #define Guestfs_val(v) (*((guestfs_h **)Data_custom_val(v)))
 extern void guestfs_int_ocaml_raise_error (guestfs_h *g, const char *func)
   Noreturn;
-- 
2.18.4