[json-glib] path: Add some more validation points



commit e8fa85705e48d03742eb351addbad53be4d8e60b
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Wed Jun 1 07:55:17 2011 +0100

    path: Add some more validation points
    
    Especially for the slice syntax.

 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);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]