Ejemplo n.º 1
0
static void
test_no_nul_byte(void)
{
    struct sol_buffer buf;
    int32_t backend;
    int32_t value = 0xdeadbeef;
    int err;

    sol_buffer_init_flags(&buf, &backend, sizeof(backend),
        SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED | SOL_BUFFER_FLAGS_NO_NUL_BYTE);

    err = sol_buffer_ensure(&buf, sizeof(int32_t));
    ASSERT_INT_EQ(err, 0);

    err = sol_buffer_append_slice(&buf, SOL_STR_SLICE_STR((const char *)&value, sizeof(value)));
    ASSERT_INT_EQ(err, 0);

    err = sol_buffer_append_slice(&buf, SOL_STR_SLICE_STR((const char *)&value, sizeof(value)));
    ASSERT_INT_NE(err, 0);

    sol_buffer_fini(&buf);

    sol_buffer_init_flags(&buf, NULL, 0, SOL_BUFFER_FLAGS_NO_NUL_BYTE);
    err = sol_buffer_append_printf(&buf, "123");
    ASSERT_INT_EQ(err, 0);
    err = sol_buffer_append_printf(&buf, "4");
    ASSERT_INT_EQ(err, 0);

    ASSERT(sol_str_slice_eq(sol_buffer_get_slice(&buf),
        SOL_STR_SLICE_STR("1234", 4)));
    sol_buffer_fini(&buf);
}
static struct sol_str_slice
get_module_for_type(const char *type)
{
    char *sep;

    sep = strchr(type, MODULE_NAME_SEPARATOR);
    if (!sep)
        return SOL_STR_SLICE_STR(type, strlen(type));
    return SOL_STR_SLICE_STR(type, sep -  type);
}
Ejemplo n.º 3
0
static bool
_level_str_parse(const char *buf, size_t buflen, uint8_t *storage)
{
    int16_t found;
    static const struct sol_str_table table[] = {
        SOL_STR_TABLE_ITEM("CRI",      SOL_LOG_LEVEL_CRITICAL),
        SOL_STR_TABLE_ITEM("CRIT",     SOL_LOG_LEVEL_CRITICAL),
        SOL_STR_TABLE_ITEM("CRITICAL", SOL_LOG_LEVEL_CRITICAL),
        SOL_STR_TABLE_ITEM("DBG",      SOL_LOG_LEVEL_DEBUG),
        SOL_STR_TABLE_ITEM("DEBUG",    SOL_LOG_LEVEL_DEBUG),
        SOL_STR_TABLE_ITEM("ERR",      SOL_LOG_LEVEL_ERROR),
        SOL_STR_TABLE_ITEM("ERROR",    SOL_LOG_LEVEL_ERROR),
        SOL_STR_TABLE_ITEM("INF",      SOL_LOG_LEVEL_INFO),
        SOL_STR_TABLE_ITEM("INFO",     SOL_LOG_LEVEL_INFO),
        SOL_STR_TABLE_ITEM("WARN",     SOL_LOG_LEVEL_WARNING),
        SOL_STR_TABLE_ITEM("WARNING",  SOL_LOG_LEVEL_WARNING),
        SOL_STR_TABLE_ITEM("WRN",      SOL_LOG_LEVEL_WARNING),
        { }
    };

    if (!sol_str_table_lookup(table, SOL_STR_SLICE_STR(buf, buflen), &found))
        return false;
    *storage = found;
    return true;
}
Ejemplo n.º 4
0
static bool
json_path_parse_key_in_brackets(struct sol_json_path_scanner *scanner, struct sol_str_slice *slice)
{
    const char *p;

    p = scanner->current + 1;

    //index is a string
    if (*p == '\'') {
        //Look for first unescaped '
        for (p = p + 1; p < scanner->end; p++) {
            p = memchr(p, '\'', scanner->end - p);
            if (!p)
                return false;
            if (*(p - 1) != '\\') //is not escaped
                break;
        }
        p++;
        if (p >= scanner->end || *p != ']')
            return false;
    } else if (*p != ']') { //index is is not empty and is suppose to be a num
        p++;
        p = memchr(p, ']', scanner->end - p);
        if (!p)
            return false;

    } else
        return false;

    p++;
    *slice = SOL_STR_SLICE_STR(scanner->current, p - scanner->current);
    scanner->current += slice->len;
    return true;
}
Ejemplo n.º 5
0
/*
 * If index is between [' and '] we need to unescape the ' char and to remove
 * the [' and '] separator.
 */
static int
json_path_parse_object_key(const struct sol_str_slice slice, struct sol_buffer *buffer)
{
    const char *end, *p, *p2;
    struct sol_str_slice key;
    int r;

    if (slice.data[0] != '[') {
        sol_buffer_init_flags(buffer, (char *)slice.data, slice.len,
            SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED | SOL_BUFFER_FLAGS_NO_NUL_BYTE);
        buffer->used = buffer->capacity;
        return 0;
    }

    //remove [' and ']
    key = SOL_STR_SLICE_STR(slice.data + 2, slice.len - 4);

    //unescape '\'' if necessary
    sol_buffer_init_flags(buffer, NULL, 0, SOL_BUFFER_FLAGS_NO_NUL_BYTE);
    end = key.data + key.len;
    for (p = key.data; p < end; p = p2 + 1) {
        p2 = memchr(p, '\'', end - p);
        if (!p2)
            break;

        //Append string preceding '
        r = sol_buffer_append_slice(buffer, SOL_STR_SLICE_STR(p, p2 - p - 1));
        SOL_INT_CHECK(r, < 0, r);
        r = sol_buffer_append_char(buffer, '\'');
        SOL_INT_CHECK(r, < 0, r);
    }

    if (!buffer->data) {
        sol_buffer_init_flags(buffer, (char *)key.data, key.len,
            SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED | SOL_BUFFER_FLAGS_NO_NUL_BYTE);
        buffer->used = buffer->capacity;
        return 0;
    }

    //Append the string leftover
    r = sol_buffer_append_slice(buffer, SOL_STR_SLICE_STR(p, end - p));
    SOL_INT_CHECK(r, < 0, r);
    return 0;
}
Ejemplo n.º 6
0
/*
 * This function takes mdata->to_regexp and copies it into a struct
 * sol_buffer, with all the number ref entries already replaced by the
 * due text. It assumes that @a buf is already initialized.
 */
static int
get_unescaped_regexp_replacement_str(struct string_regexp_replace_data *mdata,
    struct sol_buffer *buf,
    int *match_vector,
    size_t match_cnt)
{
    int r;
    struct sol_str_slice slice;
    char *ptr = mdata->to_regexp;

    SOL_NULL_CHECK(buf, -EINVAL);

    /* \g<number> or \<number> syntax. Go on as far as numbers are in
     * [0-9] range. Leading zeros are permitted.
     */
    while (*ptr) {
        if (*ptr == '\\') {
            int n;
            uint64_t grp_num = 0;

            ptr++;

            if (*ptr == 'g')
                ptr++;

            for (; (n = *ptr - '0') >= 0 && n <= 9; ptr++) {
                if (!grp_num && !n) {
                    continue;
                }

                r = sol_util_uint64_mul(grp_num, 10, &grp_num);
                SOL_INT_CHECK_GOTO(r, < 0, err);

                r = sol_util_uint64_add(grp_num, n, &grp_num);
                SOL_INT_CHECK_GOTO(r, < 0, err);
            }

            if (!grp_num || grp_num > match_cnt) {
                sol_flow_send_error_packet(mdata->node, EINVAL,
                    "Could not process '%s' pattern's reference "
                    "to non-existent subpattern on '%s'",
                    mdata->to_regexp, mdata->regexp);
                r = -EINVAL;
                goto err;
            }

            slice = SOL_STR_SLICE_STR(mdata->orig_string
                + match_vector[grp_num * 2],
                match_vector[grp_num * 2 + 1] - match_vector[grp_num * 2]);
            r = sol_buffer_append_slice(buf, slice);
            SOL_INT_CHECK_GOTO(r, < 0, err);
        } else {
Ejemplo n.º 7
0
static void
test_null(void)
{
    struct sol_arena *arena;
    struct sol_str_slice dst;

    arena = sol_arena_new();
    ASSERT(arena);

    ASSERT(sol_arena_slice_dup_str(arena, &dst, NULL));
    ASSERT(sol_arena_slice_dup_str_n(arena, &dst, NULL, 0));
    ASSERT(sol_arena_slice_dup(arena, &dst, SOL_STR_SLICE_STR(NULL, 0)));
    ASSERT(!sol_arena_strdup(arena, NULL));
    ASSERT(!sol_arena_strndup(arena, NULL, 0));

    sol_arena_del(arena);
}
Ejemplo n.º 8
0
static bool
json_path_parse_key_after_dot(struct sol_json_path_scanner *scanner, struct sol_str_slice *slice)
{
    const char *start, *first_dot, *first_bracket_start, *end;

    start = scanner->current + 1;
    first_dot = memchr(start, '.', scanner->end - start);
    first_bracket_start = memchr(start, '[', scanner->end - start);

    end = get_lowest_not_null_pointer(first_dot, first_bracket_start);
    if (end == NULL)
        end = scanner->end;

    if (end == start)
        return false;

    *slice = SOL_STR_SLICE_STR(start, end - start);
    scanner->current = start + slice->len;
    return true;
}
Ejemplo n.º 9
0
SOL_API int
sol_buffer_insert_vprintf(struct sol_buffer *buf, size_t pos, const char *fmt, va_list args)
{
    char *s;
    ssize_t len;
    struct sol_str_slice slice;
    int r;

    SOL_NULL_CHECK(buf, -EINVAL);
    SOL_NULL_CHECK(fmt, -EINVAL);
    SOL_INT_CHECK(pos, > buf->used, -EINVAL);

    if (pos == buf->used)
        return sol_buffer_append_vprintf(buf, fmt, args);

    len = vasprintf(&s, fmt, args);
    if (len < 0)
        return -errno;

    slice = SOL_STR_SLICE_STR(s, len);
    r = sol_buffer_insert_slice(buf, pos, slice);
    free(s);
    return r;
}
Ejemplo n.º 10
0
static void
test_set_slice_at(void)
{
    struct sol_buffer buf;
    struct sol_str_slice slice;
    int err;

    sol_buffer_init(&buf);
    slice = sol_str_slice_from_str("World");
    err = sol_buffer_set_slice_at(&buf, 0, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("World"));
    ASSERT_STR_EQ(buf.data, "World");

    slice = sol_str_slice_from_str("Hello");
    err = sol_buffer_set_slice_at(&buf, 0, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("Hello"));
    ASSERT_STR_EQ(buf.data, "Hello");

    slice = sol_str_slice_from_str("World");
    err = sol_buffer_set_slice_at(&buf, strlen("Hello"), slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("HelloWorld"));
    ASSERT_STR_EQ(buf.data, "HelloWorld");

    slice = sol_str_slice_from_str(" -*- ");
    err = sol_buffer_set_slice_at(&buf, 2, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("He -*- rld"));
    ASSERT_STR_EQ(buf.data, "He -*- rld");

    //overlapping
    slice = SOL_STR_SLICE_STR((char *)buf.data + 3, 3);
    err = sol_buffer_set_slice_at(&buf, 7, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("He -*- -*-"));
    ASSERT_STR_EQ(buf.data, "He -*- -*-");

    slice = sol_str_slice_from_str("whatever");
    err = sol_buffer_set_slice_at(&buf, 222, slice);
    ASSERT_INT_EQ(err, -EINVAL);

    sol_buffer_fini(&buf);

    sol_buffer_init(&buf);
    slice = sol_str_slice_from_str("abcd");
    err = sol_buffer_set_slice(&buf, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("abcd"));
    ASSERT_STR_EQ(buf.data, "abcd");

    slice = sol_str_slice_from_str("XY");
    err = sol_buffer_set_slice_at(&buf, 4, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("abcdXY"));
    ASSERT_STR_EQ(buf.data, "abcdXY");
    sol_buffer_fini(&buf);

    sol_buffer_init(&buf);
    slice = sol_str_slice_from_str("abcd");
    err = sol_buffer_set_slice(&buf, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("abcd"));
    ASSERT_STR_EQ(buf.data, "abcd");

    slice = sol_str_slice_from_str("XY");
    err = sol_buffer_set_slice_at(&buf, 3, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("abcXY"));
    ASSERT_STR_EQ(buf.data, "abcXY");
    sol_buffer_fini(&buf);

    sol_buffer_init(&buf);
    slice = sol_str_slice_from_str("abcd");
    err = sol_buffer_set_slice(&buf, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("abcd"));
    ASSERT_STR_EQ(buf.data, "abcd");

    slice = sol_str_slice_from_str("XY");
    err = sol_buffer_set_slice_at(&buf, 2, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("abXY"));
    ASSERT_STR_EQ(buf.data, "abXY");
    sol_buffer_fini(&buf);

    sol_buffer_init(&buf);
    slice = sol_str_slice_from_str("abcd");
    err = sol_buffer_set_slice(&buf, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("abcd"));
    ASSERT_STR_EQ(buf.data, "abcd");

    slice = sol_str_slice_from_str("XY");
    err = sol_buffer_set_slice_at(&buf, 1, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("aXYd"));
    ASSERT_STR_EQ(buf.data, "aXYd");
    sol_buffer_fini(&buf);

    sol_buffer_init(&buf);
    slice = sol_str_slice_from_str("abcd");
    err = sol_buffer_set_slice(&buf, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("abcd"));
    ASSERT_STR_EQ(buf.data, "abcd");

    slice = sol_str_slice_from_str("XY");
    err = sol_buffer_set_slice_at(&buf, 0, slice);
    ASSERT_INT_EQ(err, 0);
    ASSERT_INT_EQ(buf.used, strlen("XYcd"));
    ASSERT_STR_EQ(buf.data, "XYcd");
    sol_buffer_fini(&buf);
}
Ejemplo n.º 11
0
SOL_API int
sol_flow_node_named_options_init_from_strv(
    struct sol_flow_node_named_options *named_opts,
    const struct sol_flow_node_type *type,
    const char *const *strv)
{
#ifndef SOL_FLOW_NODE_TYPE_DESCRIPTION_ENABLED
    SOL_WRN("This function needs NODE_DESCRIPTION=y in the build config.");
    return -ENOTSUP;
#else
    const struct sol_flow_node_options_description *desc;
    struct sol_flow_node_named_options_member *members = NULL, *m;
    uint16_t members_count = 0;
    const struct sol_flow_node_options_member_description *mdesc;
    const char *const *entry;
    int r;

    SOL_NULL_CHECK(named_opts, -EINVAL);

    if (type->init_type)
        type->init_type();
    SOL_NULL_CHECK(type->description, -EINVAL);
    SOL_NULL_CHECK(type->description->options, -EINVAL);
    SOL_NULL_CHECK(type->description->options->members, -EINVAL);

    desc = type->description->options;

    if (strv) {
        for (entry = strv; *entry; entry++) {
            members_count++;
        }
        members = calloc(members_count, sizeof(struct sol_flow_node_named_options_member));
    }

    for (entry = strv, m = members; entry && *entry != NULL; entry++, m++) {
        const char *key, *value;
        unsigned int key_len;

        if (split_option(*entry, &key, &key_len, &value)) {
            r = -EINVAL;
            SOL_DBG("Invalid option #%u format: \"%s\"", (unsigned)(entry - strv), *entry);
            goto end;
        }

        for (mdesc = desc->members; mdesc && mdesc->name; mdesc++) {
            if (sol_str_slice_str_eq(SOL_STR_SLICE_STR(key, key_len), mdesc->name))
                break;
        }
        if (!mdesc || !mdesc->name) {
            r = -EINVAL;
            SOL_DBG("Unknown option: \"%s\"", *entry);
            goto end;
        }

        m->type = sol_flow_node_options_member_type_from_string(mdesc->data_type);
        m->name = mdesc->name;

        r = sol_flow_node_named_options_parse_member(m, value, mdesc);
        if (r < 0) {
            SOL_DBG("Could not parse member #%u "
                    "name=\"%s\", type=\"%s\", option=\"%s\": %s",
                    (unsigned)(mdesc - desc->members), mdesc->name,
                    mdesc->data_type, *entry, sol_util_strerrora(-r));
            goto end;
        }

        SOL_DBG("Parsed option \"%s\" member #%u "
                "name=\"%s\", type=\"%s\", offset=%hu, size=%hu",
                *entry, (unsigned)(mdesc - desc->members), mdesc->name,
                mdesc->data_type, mdesc->offset, mdesc->size);
    }

    named_opts->members = members;
    members = NULL;
    named_opts->count = members_count;
    r = 0;

end:
    free(members);
    return r;
#endif
}
Ejemplo n.º 12
0
            if (!grp_num || grp_num > match_cnt) {
                sol_flow_send_error_packet(mdata->node, EINVAL,
                    "Could not process '%s' pattern's reference "
                    "to non-existent subpattern on '%s'",
                    mdata->to_regexp, mdata->regexp);
                r = -EINVAL;
                goto err;
            }

            slice = SOL_STR_SLICE_STR(mdata->orig_string
                + match_vector[grp_num * 2],
                match_vector[grp_num * 2 + 1] - match_vector[grp_num * 2]);
            r = sol_buffer_append_slice(buf, slice);
            SOL_INT_CHECK_GOTO(r, < 0, err);
        } else {
            slice = SOL_STR_SLICE_STR(ptr++, 1);
            r = sol_buffer_append_slice(buf, slice);
            SOL_INT_CHECK_GOTO(r, < 0, err);
        }
    }

    if (buf->used >= (SIZE_MAX - 1) ||
        sol_buffer_ensure(buf, buf->used + 1) < 0)
        goto err;
    *(char *)sol_buffer_at(buf, buf->used) = '\0';

    return 0;

err:
    return r;
}