[Libguestfs] [PATCH 4/7] java: Stop using the safe_malloc, etc. functions.

Richard W.M. Jones rjones at redhat.com
Fri Feb 5 14:21:38 UTC 2016


---
 generator/java.ml                                  | 80 ++++++++++++++++------
 generator/main.ml                                  |  1 +
 java/Makefile.am                                   |  3 +-
 .../et/libguestfs/LibGuestFSOutOfMemory.java       | 37 ++++++++++
 java/examples/guestfs-java.pod                     |  3 +
 5 files changed, 102 insertions(+), 22 deletions(-)
 create mode 100644 java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java

diff --git a/generator/java.ml b/generator/java.ml
index 08e3a5f..7bcd329 100644
--- a/generator/java.ml
+++ b/generator/java.ml
@@ -576,7 +576,7 @@ struct callback_data {
   jmethodID method;      // callback.event method
 };
 
-static struct callback_data **get_all_event_callbacks (guestfs_h *g, size_t *len_rtn);
+static struct callback_data **get_all_event_callbacks (JNIEnv *env, guestfs_h *g, size_t *len_rtn);
 
 /* Note that this function returns.  The exception is not thrown
  * until after the wrapper function returns.
@@ -590,6 +590,18 @@ throw_exception (JNIEnv *env, const char *msg)
   (*env)->ThrowNew (env, cl, msg);
 }
 
+/* Note that this function returns.  The exception is not thrown
+ * until after the wrapper function returns.
+ */
+static void
+throw_out_of_memory (JNIEnv *env, const char *msg)
+{
+  jclass cl;
+  cl = (*env)->FindClass (env,
+                          \"com/redhat/et/libguestfs/LibGuestFSOutOfMemory\");
+  (*env)->ThrowNew (env, cl, msg);
+}
+
 JNIEXPORT jlong JNICALL
 Java_com_redhat_et_libguestfs_GuestFS__1create (JNIEnv *env,
                                                 jobject obj_unused, jint flags)
@@ -617,7 +629,7 @@ Java_com_redhat_et_libguestfs_GuestFS__1close
    * user deletes events in one of the callbacks that we are
    * about to invoke, resulting in a double-free.  XXX
    */
-  data = get_all_event_callbacks (g, &len);
+  data = get_all_event_callbacks (env, g, &len);
 
   guestfs_close (g);
 
@@ -717,7 +729,11 @@ Java_com_redhat_et_libguestfs_GuestFS__1set_1event_1callback
     return -1;
   }
 
-  data = guestfs_int_safe_malloc (g, sizeof *data);
+  data = malloc (sizeof *data);
+  if (data == NULL) {
+    throw_out_of_memory (env, \"malloc\");
+    return -1;
+  }
   (*env)->GetJavaVM (env, &data->jvm);
   data->method = method;
 
@@ -779,7 +795,7 @@ Java_com_redhat_et_libguestfs_GuestFS__1event_1to_1string
 }
 
 static struct callback_data **
-get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
+get_all_event_callbacks (JNIEnv *env, guestfs_h *g, size_t *len_rtn)
 {
   struct callback_data **r;
   size_t i;
@@ -796,7 +812,11 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
   }
 
   /* Copy them into the return array. */
-  r = guestfs_int_safe_malloc (g, sizeof (struct callback_data *) * (*len_rtn));
+  r = malloc (sizeof (struct callback_data *) * (*len_rtn));
+  if (r == NULL) {
+    throw_out_of_memory (env, \"malloc\");
+    return NULL;
+  }
 
   i = 0;
   data = guestfs_first_private (g, &key);
@@ -961,6 +981,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
       pr "\n";
 
       (* Get the parameters. *)
+      let add_ret_error_label = ref false in
       List.iter (
         function
         | Pathname n
@@ -981,7 +1002,12 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
             pr "  %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
         | StringList n | DeviceList n | FilenameList n ->
             pr "  %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
-            pr "  %s = guestfs_int_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
+            pr "  %s = malloc (sizeof (char *) * (%s_len+1));\n" n n;
+            pr "  if (%s == NULL) {\n" n;
+            pr "    throw_out_of_memory (env, \"malloc\");\n";
+            pr "    goto ret_error;\n";
+            add_ret_error_label := true;
+            pr "  }\n";
             pr "  for (i = 0; i < %s_len; ++i) {\n" n;
             pr "    jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
               n;
@@ -1007,7 +1033,12 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
                 n n
           | OStringList n ->
             pr "  %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
-            pr "  %s = guestfs_int_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
+            pr "  %s = malloc (sizeof (char *) * (%s_len+1));\n" n n;
+            pr "  if (%s == NULL) {\n" n;
+            pr "    throw_out_of_memory (env, \"malloc\");\n";
+            pr "    goto ret_error;\n";
+            add_ret_error_label := true;
+            pr "  }\n";
             pr "  for (i = 0; i < %s_len; ++i) {\n" n;
             pr "    jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
               n;
@@ -1084,25 +1115,14 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
                 pr "  if (r == NULL) {\n";
            );
            pr "    throw_exception (env, guestfs_last_error (g));\n";
-           (match ret with
-            | RErr ->
-                pr "    return;\n"
-            | RInt _
-            | RInt64 _
-            | RBool _ ->
-                pr "    return -1;\n"
-            | RConstString _ | RConstOptString _ | RString _
-            | RBufferOut _
-            | RStruct _ | RHashtable _
-            | RStringList _ | RStructList _ ->
-                pr "    return NULL;\n"
-           );
+           pr "    goto ret_error;\n";
+           add_ret_error_label := true;
            pr "  }\n"
       );
 
       (* Return value. *)
       (match ret with
-       | RErr -> ()
+       | RErr -> pr "  return;\n";
        | RInt _ -> pr "  return (jint) r;\n"
        | RBool _ -> pr "  return (jboolean) r;\n"
        | RInt64 _ -> pr "  return (jlong) r;\n"
@@ -1140,6 +1160,24 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
            pr "  return jr;\n"
       );
 
+      if !add_ret_error_label then (
+        pr "\n";
+        pr " ret_error:\n";
+        (match ret with
+         | RErr ->
+            pr "  return;\n"
+         | RInt _
+         | RInt64 _
+         | RBool _ ->
+            pr "  return -1;\n"
+         | RConstString _ | RConstOptString _ | RString _
+         | RBufferOut _
+         | RStruct _ | RHashtable _
+         | RStringList _ | RStructList _ ->
+            pr "  return NULL;\n"
+        );
+      );
+
       pr "}\n";
       pr "\n"
   ) external_functions_sorted
diff --git a/generator/main.ml b/generator/main.ml
index 0230a2f..b209511 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -145,6 +145,7 @@ Run it from the top source directory using the command
   ) external_structs;
   delete_except_generated
     ~skip:["java/com/redhat/et/libguestfs/LibGuestFSException.java";
+           "java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java";
            "java/com/redhat/et/libguestfs/EventCallback.java"]
     "java/com/redhat/et/libguestfs/*.java";
 
diff --git a/java/Makefile.am b/java/Makefile.am
index 8cfda74..0651fd3 100644
--- a/java/Makefile.am
+++ b/java/Makefile.am
@@ -31,7 +31,8 @@ include $(srcdir)/Makefile.inc
 java_sources = \
 	$(java_built_sources) \
 	com/redhat/et/libguestfs/EventCallback.java \
-	com/redhat/et/libguestfs/LibGuestFSException.java
+	com/redhat/et/libguestfs/LibGuestFSException.java \
+	com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java
 
 java_tests = \
 	Bindtests.java \
diff --git a/java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java b/java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java
new file mode 100644
index 0000000..bc4c929
--- /dev/null
+++ b/java/com/redhat/et/libguestfs/LibGuestFSOutOfMemory.java
@@ -0,0 +1,37 @@
+/* libguestfs Java bindings
+ * Copyright (C) 2009-2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package com.redhat.et.libguestfs;
+
+/**
+ * Libguestfs out of memory class.
+ * <p>
+ * This exception is thrown when malloc or a similar call fails
+ * in the bindings.
+ *
+ * @author rjones
+ * @see Error
+ */
+public class LibGuestFSOutOfMemory extends Error {
+    private static final long serialVersionUID = 1L;
+
+    public LibGuestFSOutOfMemory (String msg)
+    {
+        super (msg);
+    }
+}
diff --git a/java/examples/guestfs-java.pod b/java/examples/guestfs-java.pod
index 53276e8..bcff388 100644
--- a/java/examples/guestfs-java.pod
+++ b/java/examples/guestfs-java.pod
@@ -38,6 +38,9 @@ is the error message (a C<String>).
 
 Calling any method on a closed handle raises the same exception.
 
+If L<malloc(3)> or some other allocation fails inside the bindings,
+the C<LibGuestFSOutOfMemory> exception is thrown.
+
 =head2 EVENTS
 
 The L<libguestfs event API|guestfs(3)/EVENTS> is fully supported from
-- 
2.5.0




More information about the Libguestfs mailing list