Pino Toscano
2014-Feb-10 10:12 UTC
[Libguestfs] [PATCH 0/4] add GUID validation (RHBZ#1008417)
Hi,
this patch serie adds a new GUID type in the generator, which would do
the same as String, but also validating (just in the C output) the
passed GUID string.
This allows to reject invalid GUIDs before passing them to low-level
tools.
Pino Toscano (4):
utils: add a function to validate a GUID string
generator: add a GUID parameter type
generator: generate code for parameter validation
actions/part_set_gpt_type: set type of "guid" parameter as
"GUID"
(RHBZ#1008417).
generator/actions.ml | 11 +++++++++-
generator/bindtests.ml | 3 ++-
generator/c.ml | 54 ++++++++++++++++++++++++++++++++++++++++++++----
generator/csharp.ml | 6 ++++--
generator/daemon.ml | 4 ++--
generator/erlang.ml | 3 ++-
generator/fish.ml | 11 ++++++----
generator/gobject.ml | 8 ++++---
generator/golang.ml | 9 +++++---
generator/haskell.ml | 8 +++----
generator/java.ml | 15 +++++++++-----
generator/lua.ml | 6 +++---
generator/ocaml.ml | 9 +++++---
generator/perl.ml | 8 +++----
generator/php.ml | 12 ++++++-----
generator/python.ml | 12 +++++------
generator/ruby.ml | 4 ++--
generator/tests_c_api.ml | 6 ++++--
generator/types.ml | 6 ++++++
generator/utils.ml | 3 ++-
generator/xdr.ml | 2 +-
src/guestfs-internal.h | 3 +++
src/test-utils.c | 14 +++++++++++++
src/utils.c | 44 +++++++++++++++++++++++++++++++++++++++
24 files changed, 204 insertions(+), 57 deletions(-)
--
1.8.3.1
Pino Toscano
2014-Feb-10 10:12 UTC
[Libguestfs] [PATCH 1/4] utils: add a function to validate a GUID string
---
src/guestfs-internal.h | 3 +++
src/test-utils.c | 14 ++++++++++++++
src/utils.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 3752f79..545146f 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -833,4 +833,7 @@ extern void guestfs___cleanup_cmd_close (struct command **);
/* launch-direct.c */
extern char *guestfs___drive_source_qemu_param (guestfs_h *g, const struct
drive_source *src);
+/* utils.c */
+extern int guestfs___validate_guid (const char *);
+
#endif /* GUESTFS_INTERNAL_H_ */
diff --git a/src/test-utils.c b/src/test-utils.c
index 8ee2873..089d6b8 100644
--- a/src/test-utils.c
+++ b/src/test-utils.c
@@ -24,6 +24,7 @@
#include <assert.h>
#include "guestfs.h"
+#include "guestfs-internal.h"
#include "guestfs-internal-frontend.h"
/* Test guestfs___split_string. */
@@ -145,12 +146,25 @@ test_join (void)
free (ret);
}
+/* Test guestfs___validate_guid. */
+static void
+test_validate_guid (void)
+{
+ assert (guestfs___validate_guid ("") == 0);
+ assert (guestfs___validate_guid ("1") == 0);
+ assert (guestfs___validate_guid
("21EC20203AEA1069A2DD08002B30309D") == 0);
+
+ assert (guestfs___validate_guid
("{21EC2020-3AEA-1069-A2DD-08002B30309D}") == 1);
+ assert (guestfs___validate_guid
("21EC2020-3AEA-1069-A2DD-08002B30309D") == 1);
+}
+
int
main (int argc, char *argv[])
{
test_split ();
test_concat ();
test_join ();
+ test_validate_guid ();
exit (EXIT_SUCCESS);
}
diff --git a/src/utils.c b/src/utils.c
index 5eebdf6..45adc3d 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -28,7 +28,10 @@
#include <sys/wait.h>
#include <libintl.h>
+#include "c-ctype.h"
+
#include "guestfs.h"
+#include "guestfs-internal.h"
#include "guestfs-internal-frontend.h"
/* Note that functions in libutils are used by the tools and language
@@ -268,3 +271,44 @@ guestfs___drive_name (size_t index, char *ret)
*ret = '\0';
return ret;
}
+
+/* Check whether a string supposed to contain a GUID actually contains it.
+ * It can recognize strings either as
'{21EC2020-3AEA-1069-A2DD-08002B30309D}'
+ * or '21EC2020-3AEA-1069-A2DD-08002B30309D'.
+ */
+int
+guestfs___validate_guid (const char *str)
+{
+ int len = strlen (str);
+ switch (len) {
+ case 36:
+ break;
+ case 38:
+ if (str[0] == '{' && str[len -1] == '}') {
+ ++str;
+ len -= 2;
+ break;
+ }
+ return 0;
+ default:
+ return 0;
+ }
+
+ for (int i = 0; i < len; ++i) {
+ switch (i) {
+ case 8:
+ case 13:
+ case 18:
+ case 23:
+ if (str[i] != '-')
+ return 0;
+ break;
+ default:
+ if (!c_isalnum (str[i]))
+ return 0;
+ break;
+ }
+ }
+
+ return 1;
+}
--
1.8.3.1
Pino Toscano
2014-Feb-10 10:12 UTC
[Libguestfs] [PATCH 2/4] generator: add a GUID parameter type
At the moment it is basically the change as String, and it is mapped as
if it was such.
---
generator/bindtests.ml | 3 ++-
generator/c.ml | 11 +++++++----
generator/csharp.ml | 6 ++++--
generator/daemon.ml | 4 ++--
generator/erlang.ml | 3 ++-
generator/fish.ml | 11 +++++++----
generator/gobject.ml | 8 +++++---
generator/golang.ml | 9 ++++++---
generator/haskell.ml | 8 ++++----
generator/java.ml | 15 ++++++++++-----
generator/lua.ml | 6 +++---
generator/ocaml.ml | 9 ++++++---
generator/perl.ml | 8 ++++----
generator/php.ml | 12 +++++++-----
generator/python.ml | 12 ++++++------
generator/ruby.ml | 4 ++--
generator/tests_c_api.ml | 6 ++++--
generator/types.ml | 6 ++++++
generator/utils.ml | 3 ++-
generator/xdr.ml | 2 +-
20 files changed, 90 insertions(+), 56 deletions(-)
diff --git a/generator/bindtests.ml b/generator/bindtests.ml
index 78b0c8d..9f459ac 100644
--- a/generator/bindtests.ml
+++ b/generator/bindtests.ml
@@ -131,7 +131,8 @@ print_strings (guestfs_h *g, char *const *argv)
| String n
| FileIn n
| FileOut n
- | Key n -> pr " fprintf (fp, \"%%s\\n\",
%s);\n" n
+ | Key n
+ | GUID n -> pr " fprintf (fp, \"%%s\\n\",
%s);\n" n
| BufferIn n ->
pr " {\n";
pr " size_t i;\n";
diff --git a/generator/c.ml b/generator/c.ml
index 5fbae74..e2d5754 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -122,7 +122,8 @@ let rec generate_prototype ?(extern = true) ?(static =
false)
| Device n | Dev_or_Path n
| String n
| OptString n
- | Key n ->
+ | Key n
+ | GUID n ->
next ();
pr "const char *%s" n
| Mountable n | Mountable_or_Path n ->
@@ -1243,7 +1244,8 @@ and generate_client_actions hash () | StringList n
| DeviceList n
| Key n
- | Pointer (_, n) ->
+ | Pointer (_, n)
+ | GUID n ->
pr " if (%s == NULL) {\n" n;
pr " error (g, \"%%s: %%s: parameter cannot be
NULL\",\n";
pr " \"%s\", \"%s\");\n"
c_name n;
@@ -1356,7 +1358,8 @@ and generate_client_actions hash () | Pathname n
| Dev_or_Path n | Mountable_or_Path n
| FileIn n
- | FileOut n ->
+ | FileOut n
+ | GUID n ->
(* guestfish doesn't support string escaping, so neither do we *)
pr " fprintf (trace_buffer.fp, \"
\\\"%%s\\\"\", %s);\n" n
| Key n ->
@@ -1678,7 +1681,7 @@ and generate_client_actions hash () function
| Pathname n | Device n | Mountable n | Dev_or_Path n
| Mountable_or_Path n | String n
- | Key n ->
+ | Key n | GUID n ->
pr " args.%s = (char *) %s;\n" n n
| OptString n ->
pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
diff --git a/generator/csharp.ml b/generator/csharp.ml
index 536f532..c2b01ba 100644
--- a/generator/csharp.ml
+++ b/generator/csharp.ml
@@ -192,7 +192,8 @@ namespace Guestfs
| OptString n
| FileIn n | FileOut n
| Key n
- | BufferIn n ->
+ | BufferIn n
+ | GUID n ->
pr ", [In] string %s" n
| StringList n | DeviceList n ->
pr ", [In] string[] %s" n
@@ -220,7 +221,8 @@ namespace Guestfs
| OptString n
| FileIn n | FileOut n
| Key n
- | BufferIn n ->
+ | BufferIn n
+ | GUID n ->
next (); pr "string %s" n
| StringList n | DeviceList n ->
next (); pr "string[] %s" n
diff --git a/generator/daemon.ml b/generator/daemon.ml
index 8a759f7..548982b 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -250,7 +250,7 @@ cleanup_free_mountable (mountable_t *mountable)
function
| Device n | Dev_or_Path n ->
pr " CLEANUP_FREE char *%s = NULL;\n" n
- | Pathname n | String n | Key n | OptString n ->
+ | Pathname n | String n | Key n | OptString n | GUID n ->
pr " const char *%s;\n" n
| Mountable n | Mountable_or_Path n ->
pr " CLEANUP_FREE_MOUNTABLE mountable_t %s\n" n;
@@ -346,7 +346,7 @@ cleanup_free_mountable (mountable_t *mountable)
| Mountable_or_Path n ->
pr " REQUIRE_ROOT_OR_RESOLVE_MOUNTABLE (args.%s, %s, %s,
goto done);\n"
n n (if is_filein then "cancel_receive ()" else
"");
- | String n | Key n -> pr_args n
+ | String n | Key n | GUID n -> pr_args n
| OptString n -> pr " %s = args.%s ? *args.%s :
NULL;\n" n n n
| StringList n ->
pr " /* Ugly, but safe and avoids copying the strings.
*/\n";
diff --git a/generator/erlang.ml b/generator/erlang.ml
index b52cf1f..f0c9c6a 100644
--- a/generator/erlang.ml
+++ b/generator/erlang.ml
@@ -297,7 +297,8 @@ extern int64_t get_int64 (ETERM *term);
| String n
| FileIn n
| FileOut n
- | Key n ->
+ | Key n
+ | GUID n ->
pr " CLEANUP_FREE char *%s = erl_iolist_to_string (ARG
(%d));\n" n i
| OptString n ->
pr " CLEANUP_FREE char *%s;\n" n;
diff --git a/generator/fish.ml b/generator/fish.ml
index 7bde1ff..477fb29 100644
--- a/generator/fish.ml
+++ b/generator/fish.ml
@@ -326,7 +326,8 @@ Guestfish will prompt for these separately."
function
| Device n | Mountable n
| String n
- | OptString n -> pr " const char *%s;\n" n
+ | OptString n
+ | GUID n -> pr " const char *%s;\n" n
| Pathname n
| Dev_or_Path n | Mountable_or_Path n
| FileIn n
@@ -420,7 +421,7 @@ Guestfish will prompt for these separately."
List.iter (
function
| Device name | Mountable name
- | String name ->
+ | String name | GUID name ->
pr " %s = argv[i++];\n" name
| Pathname name
| Dev_or_Path name | Mountable_or_Path name ->
@@ -633,7 +634,8 @@ Guestfish will prompt for these separately."
function
| Device _ | Mountable _ | String _
| OptString _
- | BufferIn _ -> ()
+ | BufferIn _
+ | GUID _ -> ()
| Bool name
| Int name | Int64 name ->
pr " out_%s:\n" name
@@ -865,7 +867,8 @@ and generate_fish_actions_pod () List.iter (
function
| Pathname n | Device n | Mountable n
- | Dev_or_Path n | Mountable_or_Path n | String n ->
+ | Dev_or_Path n | Mountable_or_Path n | String n
+ | GUID n ->
pr " %s" n
| OptString n -> pr " %s" n
| StringList n | DeviceList n -> pr " '%s ...'" n
diff --git a/generator/gobject.ml b/generator/gobject.ml
index 4159c1e..3cbc9c0 100644
--- a/generator/gobject.ml
+++ b/generator/gobject.ml
@@ -81,7 +81,8 @@ let generate_gobject_proto name ?(single_line = true)
| OptString n
| Key n
| FileIn n
- | FileOut n ->
+ | FileOut n
+ | GUID n ->
pr "const gchar *%s" n
| StringList n
| DeviceList n ->
@@ -1031,7 +1032,7 @@ guestfs_session_close(GuestfsSession *session, GError
**err)
pr " (type gint32):"
| Int64 _ ->
pr " (type gint64):"
- | String _ | Key _ ->
+ | String _ | Key _ | GUID _ ->
pr " (transfer none) (type utf8):"
| OptString _ ->
pr " (transfer none) (type utf8) (allow-none):"
@@ -1190,7 +1191,8 @@ guestfs_session_close(GuestfsSession *session, GError
**err)
| Bool n | Int n | Int64 n | String n | Device n | Mountable n
| Pathname n | Dev_or_Path n | Mountable_or_Path n
| OptString n | StringList n
- | DeviceList n | Key n | FileIn n | FileOut n ->
+ | DeviceList n | Key n | FileIn n | FileOut n
+ | GUID n ->
pr "%s" n
| Pointer _ ->
failwith "gobject bindings do not support Pointer
arguments"
diff --git a/generator/golang.ml b/generator/golang.ml
index 82c1a0d..e67ca1b 100644
--- a/generator/golang.ml
+++ b/generator/golang.ml
@@ -311,7 +311,8 @@ func return_hashtable (argv **C.char) map[string]string {
| Dev_or_Path n
| Mountable_or_Path n
| Key n
- | FileIn n | FileOut n -> pr "%s string" n
+ | FileIn n | FileOut n
+ | GUID n -> pr "%s string" n
| OptString n -> pr "%s *string" n
| StringList n
| DeviceList n -> pr "%s []string" n
@@ -366,7 +367,8 @@ func return_hashtable (argv **C.char) map[string]string {
| Dev_or_Path n
| Mountable_or_Path n
| Key n
- | FileIn n | FileOut n ->
+ | FileIn n | FileOut n
+ | GUID n ->
pr "\n";
pr " c_%s := C.CString (%s)\n" n n;
pr " defer C.free (unsafe.Pointer (c_%s))\n" n
@@ -450,7 +452,8 @@ func return_hashtable (argv **C.char) map[string]string {
| Mountable_or_Path n
| OptString n
| Key n
- | FileIn n | FileOut n -> pr "c_%s" n
+ | FileIn n | FileOut n
+ | GUID n -> pr "c_%s" n
| StringList n
| DeviceList n -> pr "c_%s" n
| BufferIn n -> pr "c_%s, C.size_t (len (%s))" n n
diff --git a/generator/haskell.ml b/generator/haskell.ml
index 0329311..ca2a1ce 100644
--- a/generator/haskell.ml
+++ b/generator/haskell.ml
@@ -142,7 +142,7 @@ assocListOfHashtable (a:b:rest) = (a,b) :
assocListOfHashtable rest
| FileOut n
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n | String n
- | Key n ->
+ | Key n | GUID n ->
pr "withCString %s $ \\%s -> " n n
| BufferIn n ->
pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
@@ -162,7 +162,7 @@ assocListOfHashtable (a:b:rest) = (a,b) :
assocListOfHashtable rest
| Dev_or_Path n | Mountable_or_Path n
| String n | OptString n
| StringList n | DeviceList n
- | Key n -> n
+ | Key n | GUID n -> n
| BufferIn n -> sprintf "%s (fromIntegral %s_size)" n
n
) args in
pr "withForeignPtr h (\\p -> c_%s %s)\n" name
@@ -218,7 +218,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret,
args, optargs) (match arg with
| Pathname _ | Device _ | Mountable _
| Dev_or_Path _ | Mountable_or_Path _ | String _
- | Key _ ->
+ | Key _ | GUID _ ->
pr "CString"
| BufferIn _ ->
pr "CString -> CInt"
@@ -261,7 +261,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret,
args, optargs) (match arg with
| Pathname _ | Device _ | Mountable _
| Dev_or_Path _ | Mountable_or_Path _ | String _
- | Key _ ->
+ | Key _ | GUID _ ->
pr "String"
| BufferIn _ ->
pr "String"
diff --git a/generator/java.ml b/generator/java.ml
index ec89f3b..2e54483 100644
--- a/generator/java.ml
+++ b/generator/java.ml
@@ -452,7 +452,8 @@ and generate_java_prototype ?(public=false) ?(privat=false)
?(native=false)
| OptString n
| FileIn n
| FileOut n
- | Key n ->
+ | Key n
+ | GUID n ->
pr "String %s" n
| BufferIn n ->
pr "byte[] %s" n
@@ -812,7 +813,8 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| OptString n
| FileIn n
| FileOut n
- | Key n ->
+ | Key n
+ | GUID n ->
pr ", jstring j%s" n
| BufferIn n ->
pr ", jbyteArray j%s" n
@@ -881,7 +883,8 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| OptString n
| FileIn n
| FileOut n
- | Key n ->
+ | Key n
+ | GUID n ->
pr " const char *%s;\n" n
| BufferIn n ->
pr " char *%s;\n" n;
@@ -937,7 +940,8 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| String n
| FileIn n
| FileOut n
- | Key n ->
+ | Key n
+ | GUID n ->
pr " %s = (*env)->GetStringUTFChars (env, j%s,
NULL);\n" n n
| OptString n ->
(* This is completely undocumented, but Java null becomes
@@ -1004,7 +1008,8 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| String n
| FileIn n
| FileOut n
- | Key n ->
+ | Key n
+ | GUID n ->
pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n"
n n
| OptString n ->
pr " if (j%s)\n" n;
diff --git a/generator/lua.ml b/generator/lua.ml
index 3d7c238..9bd4006 100644
--- a/generator/lua.ml
+++ b/generator/lua.ml
@@ -461,7 +461,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
function
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n | String n
- | FileIn n | FileOut n | Key n ->
+ | FileIn n | FileOut n | Key n | GUID n ->
pr " const char *%s;\n" n
| BufferIn n ->
pr " const char *%s;\n" n;
@@ -492,7 +492,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
function
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n | String n
- | FileIn n | FileOut n | Key n ->
+ | FileIn n | FileOut n | Key n | GUID n ->
pr " %s = luaL_checkstring (L, %d);\n" n i
| BufferIn n ->
pr " %s = luaL_checklstring (L, %d, &%s_size);\n" n
i n
@@ -556,7 +556,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
| FileIn _ | FileOut _ | Key _
| BufferIn _ | OptString _
| Bool _ | Int _ | Int64 _
- | Pointer _ -> ()
+ | Pointer _ | GUID _ -> ()
| StringList n | DeviceList n ->
pr " free (%s);\n" n
) args;
diff --git a/generator/ocaml.ml b/generator/ocaml.ml
index 2e8fc64..78cff89 100644
--- a/generator/ocaml.ml
+++ b/generator/ocaml.ml
@@ -501,7 +501,8 @@ copy_table (char * const * argv)
| String n
| FileIn n
| FileOut n
- | Key n ->
+ | Key n
+ | GUID n ->
(* Copy strings in case the GC moves them: RHBZ#604691 *)
pr " char *%s = guestfs___safe_strdup (g, String_val
(%sv));\n" n n
| OptString n ->
@@ -585,7 +586,8 @@ copy_table (char * const * argv)
function
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n | String n
- | OptString n | FileIn n | FileOut n | BufferIn n | Key n ->
+ | OptString n | FileIn n | FileOut n | BufferIn n
+ | Key n | GUID n ->
pr " free (%s);\n" n
| StringList n | DeviceList n ->
pr " guestfs___free_string_list (%s);\n" n;
@@ -715,7 +717,8 @@ and generate_ocaml_function_type ?(extra_unit = false) (ret,
args, optargs) function
| Pathname _ | Device _ | Mountable _
| Dev_or_Path _ | Mountable_or_Path _ | String _
- | FileIn _ | FileOut _ | BufferIn _ | Key _ -> pr "string ->
"
+ | FileIn _ | FileOut _ | BufferIn _ | Key _
+ | GUID _ -> pr "string -> "
| OptString _ -> pr "string option -> "
| StringList _ | DeviceList _ -> pr "string array -> "
| Bool _ -> pr "bool -> "
diff --git a/generator/perl.ml b/generator/perl.ml
index a87ea26..9d368a2 100644
--- a/generator/perl.ml
+++ b/generator/perl.ml
@@ -354,7 +354,7 @@ PREINIT:
function
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n | String n
- | FileIn n | FileOut n | Key n ->
+ | FileIn n | FileOut n | Key n | GUID n ->
pr " char *%s;\n" n
| BufferIn n ->
pr " char *%s;\n" n;
@@ -509,7 +509,7 @@ PREINIT:
| Dev_or_Path _ | Mountable_or_Path _ | String _
| OptString _ | Bool _ | Int _ | Int64 _
| FileIn _ | FileOut _
- | BufferIn _ | Key _ | Pointer _ -> ()
+ | BufferIn _ | Key _ | Pointer _ | GUID _ -> ()
| StringList n | DeviceList n -> pr " free (%s);\n" n
) args;
@@ -937,7 +937,7 @@ errnos:
| Dev_or_Path n -> pr "[ '%s',
'string(dev_or_path)', %d ]" n i
| Mountable_or_Path n ->
pr "[ '%s', 'string(mountable_or_path)', %d
]" n i
- | String n -> pr "[ '%s', 'string', %d ]"
n i
+ | String n | GUID n -> pr "[ '%s', 'string', %d
]" n i
| FileIn n -> pr "[ '%s', 'string(filename)',
%d ]" n i
| FileOut n -> pr "[ '%s', 'string(filename)',
%d ]" n i
| Key n -> pr "[ '%s', 'string(key)', %d
]" n i
@@ -1105,7 +1105,7 @@ and generate_perl_prototype name (ret, args, optargs)
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n | String n
| OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
- | BufferIn n | Key n | Pointer (_, n) ->
+ | BufferIn n | Key n | Pointer (_, n) | GUID n ->
pr "$%s" n
| StringList n | DeviceList n ->
pr "\\@%s" n
diff --git a/generator/php.ml b/generator/php.ml
index b7526f6..580b10f 100644
--- a/generator/php.ml
+++ b/generator/php.ml
@@ -192,7 +192,8 @@ PHP_FUNCTION (guestfs_last_error)
| Dev_or_Path n | Mountable_or_Path n
| FileIn n | FileOut n | Key n
| OptString n
- | BufferIn n ->
+ | BufferIn n
+ | GUID n ->
pr " char *%s;\n" n;
pr " int %s_size;\n" n
| StringList n
@@ -235,7 +236,8 @@ PHP_FUNCTION (guestfs_last_error)
function
| String n | Device n | Mountable n | Pathname n
| Dev_or_Path n | Mountable_or_Path n
- | FileIn n | FileOut n | BufferIn n | Key n -> "s"
+ | FileIn n | FileOut n | BufferIn n | Key n
+ | GUID n -> "s"
| OptString n -> "s!"
| StringList n | DeviceList n -> "a"
| Bool n -> "b"
@@ -269,7 +271,7 @@ PHP_FUNCTION (guestfs_last_error)
| String n | Device n | Mountable n | Pathname n
| Dev_or_Path n | Mountable_or_Path n
| FileIn n | FileOut n | BufferIn n | Key n
- | OptString n ->
+ | OptString n | GUID n ->
pr ", &%s, &%s_size" n n
| StringList n | DeviceList n ->
pr ", &z_%s" n
@@ -303,7 +305,7 @@ PHP_FUNCTION (guestfs_last_error)
| String n | Device n | Mountable n | Pathname n
| Dev_or_Path n | Mountable_or_Path n
| FileIn n | FileOut n | Key n
- | OptString n ->
+ | OptString n | GUID n ->
(* Just need to check the string doesn't contain any ASCII
* NUL characters, which won't be supported by the C API.
*)
@@ -434,7 +436,7 @@ PHP_FUNCTION (guestfs_last_error)
| String n | Device n | Mountable n | Pathname n
| Dev_or_Path n | Mountable_or_Path n
| FileIn n | FileOut n | Key n
- | OptString n -> ()
+ | OptString n | GUID n -> ()
| BufferIn n -> ()
| StringList n
| DeviceList n ->
diff --git a/generator/python.ml b/generator/python.ml
index c6bfaaa..607ca88 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -281,7 +281,7 @@ put_table (char * const * const argv)
function
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n | String n | Key n
- | FileIn n | FileOut n ->
+ | FileIn n | FileOut n | GUID n ->
pr " const char *%s;\n" n
| OptString n -> pr " const char *%s;\n" n
| BufferIn n ->
@@ -319,7 +319,7 @@ put_table (char * const * const argv)
function
| Pathname _ | Device _ | Mountable _
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
- | FileIn _ | FileOut _ -> pr "s"
+ | FileIn _ | FileOut _ | GUID _ -> pr "s"
| OptString _ -> pr "z"
| StringList _ | DeviceList _ -> pr "O"
| Bool _ -> pr "i" (* XXX Python has booleans? *)
@@ -341,7 +341,7 @@ put_table (char * const * const argv)
function
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n | String n | Key n
- | FileIn n | FileOut n -> pr ", &%s" n
+ | FileIn n | FileOut n | GUID n -> pr ", &%s" n
| OptString n -> pr ", &%s" n
| StringList n | DeviceList n -> pr ", &py_%s" n
| Bool n -> pr ", &%s" n
@@ -365,7 +365,7 @@ put_table (char * const * const argv)
| Pathname _ | Device _ | Mountable _
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
- | BufferIn _ -> ()
+ | BufferIn _ | GUID _ -> ()
| StringList n | DeviceList n ->
pr " %s = get_string_list (py_%s);\n" n n;
pr " if (!%s) goto out;\n" n
@@ -502,7 +502,7 @@ put_table (char * const * const argv)
| Pathname _ | Device _ | Mountable _
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
- | BufferIn _ | Pointer _ -> ()
+ | BufferIn _ | Pointer _ | GUID _ -> ()
| StringList n | DeviceList n ->
pr " free (%s);\n" n
) args;
@@ -796,7 +796,7 @@ class GuestFS(object):
| Pathname _ | Device _ | Mountable _
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
- | BufferIn _ | Pointer _ -> ()
+ | BufferIn _ | Pointer _ | GUID _ -> ()
| StringList n | DeviceList n ->
pr " %s = list (%s)\n" n n
) args;
diff --git a/generator/ruby.ml b/generator/ruby.ml
index 6ba09dd..f2d700e 100644
--- a/generator/ruby.ml
+++ b/generator/ruby.ml
@@ -571,7 +571,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
function
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n | String n | Key n
- | FileIn n | FileOut n ->
+ | FileIn n | FileOut n | GUID n ->
pr " const char *%s = StringValueCStr (%sv);\n" n n;
| BufferIn n ->
pr " Check_Type (%sv, T_STRING);\n" n;
@@ -675,7 +675,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| Pathname _ | Device _ | Mountable _
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
- | BufferIn _ | Pointer _ -> ()
+ | BufferIn _ | Pointer _ | GUID _ -> ()
| StringList n | DeviceList n ->
pr " free (%s);\n" n
) args;
diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml
index 08ac13f..c0ebcb9 100644
--- a/generator/tests_c_api.ml
+++ b/generator/tests_c_api.ml
@@ -384,7 +384,8 @@ and generate_test_command_call ?(expect_error = false) ?test
?ret test_name cmd | Mountable_or_Path _, arg, sym
| String _, arg, sym
| OptString _, arg, sym
- | Key _, arg, sym ->
+ | Key _, arg, sym
+ | GUID _, arg, sym ->
pr " const char *%s = \"%s\";\n" sym (c_quote arg);
| BufferIn _, arg, sym ->
pr " const char *%s = \"%s\";\n" sym (c_quote arg);
@@ -504,7 +505,8 @@ and generate_test_command_call ?(expect_error = false) ?test
?ret test_name cmd | String _, _, sym
| OptString _, _, sym
| Key _, _, sym
- | FileIn _, _, sym -> pr ", %s" sym
+ | FileIn _, _, sym
+ | GUID _, _, sym -> pr ", %s" sym
| BufferIn _, _, sym -> pr ", %s, %s_size" sym sym
| FileOut _, arg, _ -> pr ", \"%s\"" (c_quote arg)
| StringList _, _, sym | DeviceList _, _, sym -> pr ", (char **)
%s" sym
diff --git a/generator/types.ml b/generator/types.ml
index 2827ea0..48ac32a 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -184,6 +184,12 @@ and argt * tests, although we should fix this in
future.
*)
| Pointer of (string * string)
+ (* const char * which represents a GUID string.
+ *
+ * It cannot be NULL, and it will be validated using
+ * guestfs___validate_guid.
+ *)
+ | GUID of string
and optargs = optargt list
diff --git a/generator/utils.ml b/generator/utils.ml
index 5828bbd..ecb35fd 100644
--- a/generator/utils.ml
+++ b/generator/utils.ml
@@ -253,7 +253,8 @@ let name_of_argt = function
| Pathname n | Device n | Mountable n | Dev_or_Path n
| Mountable_or_Path n | String n | OptString n
| StringList n | DeviceList n | Bool n | Int n | Int64 n
- | FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n) -> n
+ | FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n)
+ | GUID n -> n
let name_of_optargt = function
| OBool n | OInt n | OInt64 n | OString n | OStringList n -> n
diff --git a/generator/xdr.ml b/generator/xdr.ml
index aa1fd5d..257702a 100644
--- a/generator/xdr.ml
+++ b/generator/xdr.ml
@@ -112,7 +112,7 @@ let generate_xdr () function
| Pathname n | Device n | Mountable n | Dev_or_Path n
| Mountable_or_Path n | String n
- | Key n ->
+ | Key n | GUID n ->
pr " string %s<>;\n" n
| OptString n -> pr " guestfs_str *%s;\n" n
| StringList n | DeviceList n -> pr " guestfs_str
%s<>;\n" n
--
1.8.3.1
Pino Toscano
2014-Feb-10 10:12 UTC
[Libguestfs] [PATCH 3/4] generator: generate code for parameter validation
Implemented only in the C output, since every binding uses it anyway,
and just for the "GUID" type (since its format is well-known).
---
generator/c.ml | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/generator/c.ml b/generator/c.ml
index e2d5754..c3185be 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -1329,6 +1329,47 @@ and generate_client_actions hash () pr
"\n";
in
+ (* Generate code to check for parameter validation (where supported
+ * for the type).
+ *)
+ let check_args_validity c_name (ret, args, optargs) + let pr_newline = ref
false in
+ List.iter (
+ function
+ | GUID n ->
+ pr " if (!guestfs___validate_guid (%s)) {\n" n;
+ pr " error (g, \"%%s: %%s: parameter is not a valid
GUID\",\n";
+ pr " \"%s\", \"%s\");\n"
c_name n;
+ let errcode + match errcode_of_ret ret with
+ | `CannotReturnError -> assert false
+ | (`ErrorIsMinusOne |`ErrorIsNULL) as e -> e in
+ pr " return %s;\n" (string_of_errcode errcode);
+ pr " }\n";
+ pr_newline := true
+
+ (* not applicable *)
+ | String _
+ | Device _
+ | Mountable _
+ | Pathname _
+ | Dev_or_Path _ | Mountable_or_Path _
+ | FileIn _
+ | FileOut _
+ | BufferIn _
+ | StringList _
+ | DeviceList _
+ | Key _
+ | Pointer (_, _)
+ | OptString _
+ | Bool _
+ | Int _
+ | Int64 _ -> ()
+ ) args;
+
+ if !pr_newline then pr "\n";
+ in
+
(* Generate code to generate guestfish call traces. *)
let trace_call name c_name (ret, args, optargs) pr " if
(trace_flag) {\n";
@@ -1547,6 +1588,7 @@ and generate_client_actions hash () enter_event name;
check_null_strings c_name style;
reject_unknown_optargs c_name style;
+ check_args_validity c_name style;
trace_call name c_name style;
pr " r = guestfs__%s " c_name;
generate_c_call_args ~handle:"g"
~implicit_size_ptr:"size_r" style;
@@ -1649,6 +1691,7 @@ and generate_client_actions hash () enter_event name;
check_null_strings c_name style;
reject_unknown_optargs c_name style;
+ check_args_validity c_name style;
trace_call name c_name style;
(* Calculate the total size of all FileIn arguments to pass
--
1.8.3.1
Pino Toscano
2014-Feb-10 10:12 UTC
[Libguestfs] [PATCH 4/4] actions/part_set_gpt_type: set type of "guid" parameter as "GUID" (RHBZ#1008417).
Switch the type of the "guid" parameter from "String" to
"GUID"; this
adds the validation of the GUID as such, rejecting straight away invalid
GUIDs which otherwise could be handled badly by low-level tools (such as
sgdisk).
Add a couple of easy tests (taken from RHBZ#1008417) to
part_set_gpt_type about this.
---
generator/actions.ml | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/generator/actions.ml b/generator/actions.ml
index b665149..a6ef194 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -11339,9 +11339,18 @@ group with GUID C<diskgroup>." };
{ defaults with
name = "part_set_gpt_type";
- style = RErr, [Device "device"; Int "partnum"; String
"guid"], [];
+ style = RErr, [Device "device"; Int "partnum"; GUID
"guid"], [];
proc_nr = Some 392;
optional = Some "gdisk";
+ tests = [
+ InitGPT, Always, TestLastFail (
+ [["part_set_gpt_type"; "/dev/sda"; "1";
"f"]]), [];
+ InitGPT, Always, TestResultString (
+ [["part_set_gpt_type"; "/dev/sda"; "1";
+ "01234567-89AB-CDEF-0123-456789ABCDEF"];
+ ["part_get_gpt_type"; "/dev/sda"; "1"]],
+ "01234567-89AB-CDEF-0123-456789ABCDEF"), [];
+ ];
shortdesc = "set the type GUID of a GPT partition";
longdesc = "\
Set the type GUID of numbered GPT partition C<partnum> to C<guid>.
Return an
--
1.8.3.1
Richard W.M. Jones
2014-Feb-10 11:41 UTC
Re: [Libguestfs] [PATCH 0/4] add GUID validation (RHBZ#1008417)
On Mon, Feb 10, 2014 at 11:12:07AM +0100, Pino Toscano wrote:> Hi, > > this patch serie adds a new GUID type in the generator, which would do > the same as String, but also validating (just in the C output) the > passed GUID string. > This allows to reject invalid GUIDs before passing them to low-level > tools.Yup, this all looks fine to me. ACK. Thanks, Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v