diff options
Diffstat (limited to 'json-glib/json-path.c')
-rw-r--r-- | json-glib/json-path.c | 77 |
1 files changed, 56 insertions, 21 deletions
diff --git a/json-glib/json-path.c b/json-glib/json-path.c index 0857e05..8866c28 100644 --- a/json-glib/json-path.c +++ b/json-glib/json-path.c @@ -370,7 +370,7 @@ json_path_compile (JsonPath *path, { g_set_error_literal (error, JSON_PATH_ERROR, JSON_PATH_ERROR_INVALID_QUERY, - "Multiple roots"); + "Only one root element is allowed"); return FALSE; } @@ -378,7 +378,7 @@ json_path_compile (JsonPath *path, { g_set_error (error, JSON_PATH_ERROR, JSON_PATH_ERROR_INVALID_QUERY, - "Root node followed by '%c'", + "Root node followed by invalid character '%c'", *(p + 1)); return FALSE; } @@ -400,6 +400,14 @@ json_path_compile (JsonPath *path, { node = g_new0 (PathNode, 1); node->node_type = JSON_PATH_NODE_RECURSIVE_DESCENT; + + /* if the recursive descent operator is followed by + * an open bracket then we need to skip the second '.' + * so that the cursor will find itself on the right + * position for the next token + */ + if (*(p + 2) == '[') + p += 1; } else if (*p == '.' && *(p + 1) == '*') { @@ -587,6 +595,32 @@ json_path_compile (JsonPath *path, goto fail; } + if (slice_step == 0) + { + g_set_error (error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + "Invalid step '%d' for slice '[%d:%d]': " + "the step argument must not be zero", + slice_step, slice_start, slice_end); + goto fail; + } + + if (slice_step > 0) + { + if (slice_start >= 0 && + slice_end >= 0 && + slice_end < slice_start) + { + g_set_error (error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + "Invalid slice [%d:%d:%d]: the end " + "of the slice is smaller than the " + "start.", + slice_start, slice_end, slice_step); + goto fail; + } + } + node = g_new0 (PathNode, 1); node->node_type = JSON_PATH_NODE_ELEMENT_SLICE; node->data.slice.start = slice_start; @@ -630,6 +664,7 @@ json_path_compile (JsonPath *path, p += 1; } + /* the nodes are prepended, so we need to flip the path around */ nodes = g_list_reverse (nodes); #ifdef JSON_ENABLE_DEBUG @@ -771,7 +806,7 @@ walk_path_node (GList *path, case JSON_PATH_NODE_RECURSIVE_DESCENT: { - PathNode *tmp = path->next->data; + PathNode *next = path->next->data; switch (json_node_get_node_type (root)) { @@ -785,10 +820,10 @@ walk_path_node (GList *path, { JsonNode *m = json_object_get_member (object, l->data); - if (tmp->node_type == JSON_PATH_NODE_CHILD_MEMBER && - strcmp (tmp->data.member_name, l->data) == 0) + if (next->node_type == JSON_PATH_NODE_CHILD_MEMBER && + strcmp (next->data.member_name, l->data) == 0) { - JSON_NOTE (PATH, "entering '%s'", tmp->data.member_name); + JSON_NOTE (PATH, "entering '%s'", next->data.member_name); walk_path_node (path->next, root, results); } else @@ -812,10 +847,10 @@ walk_path_node (GList *path, { JsonNode *m = l->data; - if (tmp->node_type == JSON_PATH_NODE_CHILD_ELEMENT && - tmp->data.element_index == i) + if (next->node_type == JSON_PATH_NODE_CHILD_ELEMENT && + next->data.element_index == i) { - JSON_NOTE (PATH, "entering '%d'", tmp->data.element_index); + JSON_NOTE (PATH, "entering '%d'", next->data.element_index); walk_path_node (path->next, root, results); } else @@ -911,23 +946,23 @@ walk_path_node (GList *path, if (JSON_NODE_HOLDS_ARRAY (root)) { JsonArray *array = json_node_get_array (root); - int i, start, end; + int i, start, end, step; if (node->data.slice.start < 0) - { - start = json_array_get_length (array) - + node->data.slice.start; + start = json_array_get_length (array) + + node->data.slice.start; + else + start = node->data.slice.start; - end = json_array_get_length (array) - + node->data.slice.end; - } + if (node->data.slice.end < 0) + end = json_array_get_length (array) + + node->data.slice.end; else - { - start = node->data.slice.start; - end = node->data.slice.end; - } + end = node->data.slice.end; + + step = node->data.slice.step; - for (i = start; i < end; i += node->data.slice.step) + for (i = start; i < end; i += step) { JsonNode *element = json_array_get_element (array, i); |