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