[augeas-devel] augeas: master - * src/pathx.c: handle names with '.' properly

David Lutterkort lutter at fedoraproject.org
Mon Mar 2 19:29:52 UTC 2009


Gitweb:        http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=4e34ef9b3d0bd8c97d86e86bbba11d49f79e8a82
Commit:        4e34ef9b3d0bd8c97d86e86bbba11d49f79e8a82
Parent:        9bcd7b66aa6781d69d917166293fc80cfdab4066
Author:        David Lutterkort <lutter at redhat.com>
AuthorDate:    Mon Mar 2 11:23:44 2009 -0800
Committer:     David Lutterkort <lutter at redhat.com>
CommitterDate: Mon Mar 2 11:28:01 2009 -0800

* src/pathx.c: handle names with '.' properly

Make sure that a component ina path expression like '.bar' is parsed as a
single step (name), and not as the self axis '.' followed by some
garbage.

Bug reported by Jan Kupec
---
 src/pathx.c       |   37 +++++++++++++++++++++----------------
 tests/xpath.tests |    5 +++++
 2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/src/pathx.c b/src/pathx.c
index 5da5caf..6a4d723 100644
--- a/src/pathx.c
+++ b/src/pathx.c
@@ -1103,36 +1103,41 @@ static struct pred *parse_predicates(struct state *state) {
  */
 static struct step *parse_step(struct state *state) {
     struct step *step;
+    int explicit_axis = 0, allow_predicates = 1;
 
     if (ALLOC(step) < 0) {
         STATE_ENOMEM;
         return NULL;
     }
 
-    if (*state->pos == '.' && state->pos[1] == '.') {
-        state->pos += 2;
-        step->axis = PARENT;
-    } else if (match(state, '.')) {
-        step->axis = SELF;
-    } else {
-        step->axis = CHILD;
-        for (int i = 0; i < ARRAY_CARDINALITY(axis_names); i++) {
-            if (looking_at(state, axis_names[i], "::")) {
-                step->axis = i;
-                break;
-            }
+    step->axis = CHILD;
+    for (int i = 0; i < ARRAY_CARDINALITY(axis_names); i++) {
+        if (looking_at(state, axis_names[i], "::")) {
+            step->axis = i;
+            explicit_axis = 1;
+            break;
         }
+    }
 
-        if (! match(state, '*')) {
-            step->name = parse_name(state);
-            if (HAS_ERROR(state))
-                goto error;
+    if (! match(state, '*')) {
+        step->name = parse_name(state);
+        if (HAS_ERROR(state))
+            goto error;
+        if (! explicit_axis) {
+            if (STREQ(step->name, ".") || STREQ(step->name, "..")) {
+                step->axis = STREQ(step->name, ".") ? SELF : PARENT;
+                FREE(step->name);
+                allow_predicates = 0;
+            }
         }
+    }
 
+    if (allow_predicates) {
         step->predicates = parse_predicates(state);
         if (HAS_ERROR(state))
             goto error;
     }
+
     return step;
 
  error:
diff --git a/tests/xpath.tests b/tests/xpath.tests
index 8f89f3c..0fa1e3d 100644
--- a/tests/xpath.tests
+++ b/tests/xpath.tests
@@ -160,3 +160,8 @@ test pred-or /files/etc/hosts/*[canonical = 'localhost' or alias = 'localhost']
 
 test pred-and-or /files/etc/hosts/*[(canonical = 'localhost' or alias = 'localhost') and ipaddr = '127.0.0.1']
      /files/etc/hosts/1
+
+# We used to parse this as '/files/etc/.' followed by garbage, that
+# was silently ignored. This path must not match anything, instead of
+# every child of /files/etc
+test path-with-dot /files/etc/.notthere




More information about the augeas-devel mailing list