From 5c5cc8b7bc2588c04dd0d0472b466f978f8ac55c Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" 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 +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 +#include + +/* 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