Beispiel #1
0
static void test_one(const char *data, ...) {
        void *state = NULL;
        va_list ap;

        va_start(ap, data);

        for (;;) {
                _cleanup_free_ char *str = NULL;
                union json_value v = {};
                int t, tt;

                t = json_tokenize(&data, &str, &v, &state, NULL);
                tt = va_arg(ap, int);

                assert_se(t == tt);

                if (t == JSON_END || t < 0)
                        break;

                else if (t == JSON_STRING) {
                        const char *nn;

                        nn = va_arg(ap, const char *);
                        assert_se(streq_ptr(nn, str));

                } else if (t == JSON_REAL) {
                        double d;

                        d = va_arg(ap, double);
                        assert_se(fabs(d - v.real) < 0.001);

                } else if (t == JSON_INTEGER) {
Beispiel #2
0
static int parse_id(const void *payload, size_t size, char **ret) {
        _cleanup_free_ char *buf = NULL, *id = NULL, *other = NULL;
        union json_value v = {};
        void *json_state = NULL;
        const char *p;
        int t;

        assert(payload);
        assert(ret);

        if (size <= 0)
                return -EBADMSG;

        if (memchr(payload, 0, size))
                return -EBADMSG;

        buf = strndup(payload, size);
        if (!buf)
                return -ENOMEM;

        p = buf;
        t = json_tokenize(&p, &id, &v, &json_state, NULL);
        if (t < 0)
                return t;
        if (t != JSON_STRING)
                return -EBADMSG;

        t = json_tokenize(&p, &other, &v, &json_state, NULL);
        if (t < 0)
                return t;
        if (t != JSON_END)
                return -EBADMSG;

        if (!dkr_id_is_valid(id))
                return -EBADMSG;

        *ret = id;
        id = NULL;

        return 0;
}
Beispiel #3
0
static int parse_ancestry(const void *payload, size_t size, char ***ret) {
        _cleanup_free_ char *buf = NULL;
        void *json_state = NULL;
        const char *p;
        enum {
                STATE_BEGIN,
                STATE_ITEM,
                STATE_COMMA,
                STATE_END,
        } state = STATE_BEGIN;
        _cleanup_strv_free_ char **l = NULL;
        size_t n = 0, allocated = 0;

        if (size <= 0)
                return -EBADMSG;

        if (memchr(payload, 0, size))
                return -EBADMSG;

        buf = strndup(payload, size);
        if (!buf)
                return -ENOMEM;

        p = buf;
        for (;;) {
                _cleanup_free_ char *str;
                union json_value v = {};
                int t;

                t = json_tokenize(&p, &str, &v, &json_state, NULL);
                if (t < 0)
                        return t;

                switch (state) {

                case STATE_BEGIN:
                        if (t == JSON_ARRAY_OPEN)
                                state = STATE_ITEM;
                        else
                                return -EBADMSG;

                        break;

                case STATE_ITEM:
                        if (t == JSON_STRING) {
                                if (!dkr_id_is_valid(str))
                                        return -EBADMSG;

                                if (n+1 > LAYERS_MAX)
                                        return -EFBIG;

                                if (!GREEDY_REALLOC(l, allocated, n + 2))
                                        return -ENOMEM;

                                l[n++] = str;
                                str = NULL;
                                l[n] = NULL;

                                state = STATE_COMMA;

                        } else if (t == JSON_ARRAY_CLOSE)
                                state = STATE_END;
                        else
                                return -EBADMSG;

                        break;

                case STATE_COMMA:
                        if (t == JSON_COMMA)
                                state = STATE_ITEM;
                        else if (t == JSON_ARRAY_CLOSE)
                                state = STATE_END;
                        else
                                return -EBADMSG;
                        break;

                case STATE_END:
                        if (t == JSON_END) {

                                if (strv_isempty(l))
                                        return -EBADMSG;

                                if (!strv_is_uniq(l))
                                        return -EBADMSG;

                                l = strv_reverse(l);

                                *ret = l;
                                l = NULL;
                                return 0;
                        } else
                                return -EBADMSG;
                }

        }
}
Beispiel #4
0
static int json_tokens(const char *string, size_t size, JsonVariant ***tokens, size_t *n) {
        _cleanup_free_ char *buf = NULL;
        _cleanup_(json_variant_array_unrefp) JsonVariant **items = NULL;
        union json_value v = {};
        void *json_state = NULL;
        const char *p;
        int t, r;
        size_t allocated = 0, s = 0;

        assert(string);
        assert(n);

        if (size <= 0)
                return -EBADMSG;

        buf = strndup(string, size);
        if (!buf)
                return -ENOMEM;

        p = buf;
        for (;;) {
                _cleanup_json_variant_unref_ JsonVariant *var = NULL;
                _cleanup_free_ char *rstr = NULL;

                t = json_tokenize(&p, &rstr, &v, &json_state, NULL);

                if (t < 0)
                        return t;
                else if (t == JSON_END)
                        break;

                if (t <= JSON_ARRAY_CLOSE) {
                        r = json_variant_new(&var, JSON_VARIANT_CONTROL);
                        if (r < 0)
                                return r;
                        var->value.integer = t;
                } else {
                        switch (t) {
                        case JSON_STRING:
                                r = json_variant_new(&var, JSON_VARIANT_STRING);
                                if (r < 0)
                                        return r;
                                var->size = strlen(rstr);
                                var->string = strdup(rstr);
                                if (!var->string) {
                                        return -ENOMEM;
                                }
                                break;
                        case JSON_INTEGER:
                                r = json_variant_new(&var, JSON_VARIANT_INTEGER);
                                if (r < 0)
                                        return r;
                                var->value = v;
                                break;
                        case JSON_REAL:
                                r = json_variant_new(&var, JSON_VARIANT_REAL);
                                if (r < 0)
                                        return r;
                                var->value = v;
                                break;
                        case JSON_BOOLEAN:
                                r = json_variant_new(&var, JSON_VARIANT_BOOLEAN);
                                if (r < 0)
                                        return r;
                                var->value = v;
                                break;
                        case JSON_NULL:
                                r = json_variant_new(&var, JSON_VARIANT_NULL);
                                if (r < 0)
                                        return r;
                                break;
                        }
                }

                if (!GREEDY_REALLOC(items, allocated, s+2))
                        return -ENOMEM;

                items[s++] = var;
                items[s] = NULL;
                var = NULL;
        }

        *n = s;
        *tokens = items;
        items = NULL;

        return 0;
}