The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/1609

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Signed-off-by: Christian Brauner <[email protected]>
From 9d03851990dccf216c2b40afe0ecaea2e71ad301 Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Thu, 1 Jun 2017 23:43:16 +0200
Subject: [PATCH 1/2] confile: move idmap parser to separate helper

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/confile.c | 178 +++++++++++++++++++++++++++++++-----------------------
 1 file changed, 101 insertions(+), 77 deletions(-)

diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 4186d6347..ee15690e7 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -1979,131 +1979,156 @@ static int set_config_limit(const char *key, const 
char *value,
        return -1;
 }
 
-static int set_config_idmaps(const char *key, const char *value,
-                            struct lxc_conf *lxc_conf)
+static int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
+                       unsigned long *hostid, unsigned long *range)
 {
-       unsigned long hostid, nsid, range;
-       char type;
+       int ret = -1;
+       unsigned long tmp_hostid, tmp_nsid, tmp_range;
+       char tmp_type;
        char *window, *slide;
        char *dup = NULL;
-       struct lxc_list *idmaplist = NULL;
-       struct id_map *idmap = NULL;
-
-       if (config_value_empty(value))
-               return lxc_clear_idmaps(lxc_conf);
-
-       idmaplist = malloc(sizeof(*idmaplist));
-       if (!idmaplist)
-               goto on_error;
-
-       idmap = malloc(sizeof(*idmap));
-       if (!idmap)
-               goto on_error;
-       memset(idmap, 0, sizeof(*idmap));
 
        /* Duplicate string. */
-       dup = strdup(value);
+       dup = strdup(idmap);
        if (!dup)
                goto on_error;
 
        /* A prototypical idmap entry would be: "u 1000 1000000 65536" */
 
        /* align */
-        slide = window = dup;
-        /* skip whitespace */
-        slide += strspn(slide, " \t\r");
-        if (slide != window && *slide == '\0')
-                goto on_error;
+       slide = window = dup;
+       /* skip whitespace */
+       slide += strspn(slide, " \t\r");
+       if (slide != window && *slide == '\0')
+               goto on_error;
 
        /* Validate type. */
-        if (*slide != 'u' && *slide != 'g')
-                goto on_error;
-        /* Assign type. */
-        type = *slide;
+       if (*slide != 'u' && *slide != 'g')
+               goto on_error;
+       /* Assign type. */
+       tmp_type = *slide;
 
        /* move beyond type */
-        slide++;
+       slide++;
        /* align */
-        window = slide;
-        /* Validate that only whitespace follows. */
-        slide += strspn(slide, " \t\r");
+       window = slide;
+       /* Validate that only whitespace follows. */
+       slide += strspn(slide, " \t\r");
        /* There must be whitespace. */
-        if (slide == window)
-                goto on_error;
+       if (slide == window)
+               goto on_error;
 
-        /* Mark beginning of nsuid. */
-        window = slide;
+       /* Mark beginning of nsuid. */
+       window = slide;
        /* Validate that non-whitespace follows. */
-        slide += strcspn(slide, " \t\r");
+       slide += strcspn(slide, " \t\r");
        /* There must be non-whitespace. */
-        if (slide == window || *slide == '\0')
-                goto on_error;
-        /* Mark end of nsuid. */
-        *slide = '\0';
+       if (slide == window || *slide == '\0')
+               goto on_error;
+       /* Mark end of nsuid. */
+       *slide = '\0';
 
-        /* Parse nsuid. */
-        if (lxc_safe_ulong(window, &nsid) < 0)
-                goto on_error;
+       /* Parse nsuid. */
+       if (lxc_safe_ulong(window, &tmp_nsid) < 0)
+               goto on_error;
 
        /* Move beyond \0. */
-        slide++;
+       slide++;
        /* align */
-        window = slide;
-        /* Validate that only whitespace follows. */
-        slide += strspn(slide, " \t\r");
+       window = slide;
+       /* Validate that only whitespace follows. */
+       slide += strspn(slide, " \t\r");
        /* If there was only one whitespace then we whiped it with our \0 above.
         * So only ensure that we're not at the end of the string.
         */
        if (*slide == '\0')
-                goto on_error;
+               goto on_error;
 
-        /* Mark beginning of hostid. */
-        window = slide;
+       /* Mark beginning of hostid. */
+       window = slide;
        /* Validate that non-whitespace follows. */
-        slide += strcspn(slide, " \t\r");
+       slide += strcspn(slide, " \t\r");
        /* There must be non-whitespace. */
-        if (slide == window || *slide == '\0')
-                goto on_error;
-        /* Mark end of nsuid. */
-        *slide = '\0';
+       if (slide == window || *slide == '\0')
+               goto on_error;
+       /* Mark end of nsuid. */
+       *slide = '\0';
 
-        /* Parse hostid. */
-        if (lxc_safe_ulong(window, &hostid) < 0)
-                goto on_error;
+       /* Parse hostid. */
+       if (lxc_safe_ulong(window, &tmp_hostid) < 0)
+               goto on_error;
 
        /* Move beyond \0. */
-        slide++;
+       slide++;
        /* align */
-        window = slide;
-        /* Validate that only whitespace follows. */
-        slide += strspn(slide, " \t\r");
+       window = slide;
+       /* Validate that only whitespace follows. */
+       slide += strspn(slide, " \t\r");
        /* If there was only one whitespace then we whiped it with our \0 above.
         * So only ensure that we're not at the end of the string.
         */
-        if (*slide == '\0')
-                goto on_error;
+       if (*slide == '\0')
+               goto on_error;
 
-        /* Mark beginning of range. */
-        window = slide;
+       /* Mark beginning of range. */
+       window = slide;
        /* Validate that non-whitespace follows. */
-        slide += strcspn(slide, " \t\r");
+       slide += strcspn(slide, " \t\r");
        /* There must be non-whitespace. */
-        if (slide == window)
-                goto on_error;
+       if (slide == window)
+               goto on_error;
 
        /* The range is the last valid entry we expect. So make sure that there
         * is not trailing garbage and if there is, error out.
         */
        if (*(slide + strspn(slide, " \t\r\n")) != '\0')
-                goto on_error;
-        /* Mark end of range. */
-        *slide = '\0';
+               goto on_error;
+       /* Mark end of range. */
+       *slide = '\0';
+
+       /* Parse range. */
+       if (lxc_safe_ulong(window, &tmp_range) < 0)
+               goto on_error;
 
-        /* Parse range. */
-        if (lxc_safe_ulong(window, &range) < 0)
-                goto on_error;
+       *type = tmp_type;
+       *nsid = tmp_nsid;
+       *hostid = tmp_hostid;
+       *range = tmp_range;
 
        /* Yay, we survived. */
+       ret = 0;
+
+on_error:
+       free(dup);
+
+       return ret;
+}
+
+static int set_config_idmaps(const char *key, const char *value,
+                            struct lxc_conf *lxc_conf)
+{
+       unsigned long hostid, nsid, range;
+       char type;
+       int ret;
+       struct lxc_list *idmaplist = NULL;
+       struct id_map *idmap = NULL;
+
+       if (config_value_empty(value))
+               return lxc_clear_idmaps(lxc_conf);
+
+       idmaplist = malloc(sizeof(*idmaplist));
+       if (!idmaplist)
+               goto on_error;
+
+       idmap = malloc(sizeof(*idmap));
+       if (!idmap)
+               goto on_error;
+       memset(idmap, 0, sizeof(*idmap));
+
+       ret = parse_idmaps(value, &type, &nsid, &hostid, &range);
+       if (ret < 0)
+               goto on_error;
+
        INFO("read uid map: type %c nsid %lu hostid %lu range %lu", type, nsid, 
hostid, range);
        if (type == 'u')
                idmap->idtype = ID_TYPE_UID;
@@ -2124,7 +2149,6 @@ static int set_config_idmaps(const char *key, const char 
*value,
 on_error:
        free(idmaplist);
        free(idmap);
-       free(dup);
 
        return -1;
 }

From ef019d918762d95bb6ec03a4cbaf3094d2b1bf53 Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Thu, 1 Jun 2017 23:43:34 +0200
Subject: [PATCH 2/2] tests: add unit tests for idmap parser

Signed-off-by: Christian Brauner <[email protected]>
---
 src/tests/parse_config_file.c | 53 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/tests/parse_config_file.c b/src/tests/parse_config_file.c
index 509370615..1ae145f0c 100644
--- a/src/tests/parse_config_file.c
+++ b/src/tests/parse_config_file.c
@@ -28,6 +28,7 @@
 #include <errno.h>
 #include <string.h>
 
+#include "confile.c"
 #include "lxc/state.h"
 #include "lxctest.h"
 
@@ -103,6 +104,53 @@ static int set_get_compare_clear_save_load(struct 
lxc_container *c,
        return 0;
 }
 
+int test_idmap_parser(void)
+{
+       size_t i;
+       struct idmap_check {
+               bool is_valid;
+               const char *idmap;
+       };
+       static struct idmap_check idmaps[] = {
+               /* valid idmaps */
+               { true, "u 0 0 0"                       },
+               { true, "g 0 0 0"                       },
+               { true, "u 1000 165536 65536"           },
+               { true, "g 999 999 1"                   },
+               { true, "u    0         5000    100000" },
+               { true, "g              577     789 5"  },
+               { true, "u 65536 65536 1        "       },
+               /* invalid idmaps */
+               { false, "1u 0 0 0"                     },
+               { false, "1g 0 0 0a"                    },
+               { false, "1 u 0 0 0"                    },
+               { false, "1g 0 0 0 1"                   },
+               { false, "1u a0 b0 c0 d1"               },
+               { false, "1g 0 b0 0 d1"                 },
+               { false, "1u a0 0 c0 1"                 },
+               { false, "g -1 0 -10"                   },
+               { false, "a 1 0 10"                     },
+               { false, "u 1 1 0 10"                   },
+               { false, "g 1 0 10       z "            },
+       };
+
+       for (i = 0; i < sizeof(idmaps) / sizeof(struct idmap_check); i++) {
+               unsigned long hostid, nsid, range;
+               char type;
+               int ret;
+               ret = parse_idmaps(idmaps[i].idmap, &type, &nsid, &hostid,
+                                  &range);
+               if ((ret < 0 && idmaps[i].is_valid) ||
+                   (ret == 0 && !idmaps[i].is_valid)) {
+                       lxc_error("failed to parse idmap \"%s\"\n",
+                                 idmaps[i].idmap);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 int main(int argc, char *argv[])
 {
        struct lxc_container *c;
@@ -489,6 +537,11 @@ int main(int argc, char *argv[])
                goto non_test_error;
        }
 
+       if (test_idmap_parser() < 0) {
+               lxc_error("%s\n", "failed to test parser for \"lxc.id_map\"");
+               goto non_test_error;
+       }
+
        ret = EXIT_SUCCESS;
 non_test_error:
        c->destroy(c);
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to