Blame SOURCES/augeas-1.1.0-incl-double-slash.patch

c537d4
From 361adbf9e520d695ae13efe6084cbcdebe4779e2 Mon Sep 17 00:00:00 2001
c537d4
From: Dominic Cleal <dcleal@redhat.com>
c537d4
Date: Tue, 19 Nov 2013 09:39:23 +0000
c537d4
Subject: [PATCH] * src/transform.c (filter_matches): wrap fnmatch to ensure
c537d4
 that an incl   pattern containing "//" matches file paths
c537d4
c537d4
Fixes RHBZ#1031084
c537d4
---
c537d4
 src/transform.c   | 38 ++++++++++++++++++++++++++++++++++----
c537d4
 tests/test-save.c | 39 +++++++++++++++++++++++++++++++++++++++
c537d4
 2 files changed, 73 insertions(+), 4 deletions(-)
c537d4
c537d4
diff --git a/src/transform.c b/src/transform.c
c537d4
index 1ee8da8..ccbe422 100644
c537d4
--- a/src/transform.c
c537d4
+++ b/src/transform.c
c537d4
@@ -142,6 +142,33 @@ static char *mtime_as_string(struct augeas *aug, const char *fname) {
c537d4
     return NULL;
c537d4
 }
c537d4
 
c537d4
+/* fnmatch(3) which will match // in a pattern to a path, like glob(3) does */
c537d4
+static int fnmatch_normalize(const char *pattern, const char *string, int flags) {
c537d4
+    int i, j, r;
c537d4
+    char *pattern_norm = NULL;
c537d4
+
c537d4
+    r = ALLOC_N(pattern_norm, strlen(pattern) + 1);
c537d4
+    if (r < 0)
c537d4
+        goto error;
c537d4
+
c537d4
+    for (i = 0, j = 0; i < strlen(pattern); i++) {
c537d4
+        if (pattern[i] != '/' || pattern[i+1] != '/') {
c537d4
+            pattern_norm[j] = pattern[i];
c537d4
+            j++;
c537d4
+        }
c537d4
+    }
c537d4
+    pattern_norm[j] = 0;
c537d4
+
c537d4
+    r = fnmatch(pattern_norm, string, flags);
c537d4
+    FREE(pattern_norm);
c537d4
+    return r;
c537d4
+
c537d4
+ error:
c537d4
+    if (pattern_norm != NULL)
c537d4
+        FREE(pattern_norm);
c537d4
+    return -1;
c537d4
+}
c537d4
+
c537d4
 static bool file_current(struct augeas *aug, const char *fname,
c537d4
                          struct tree *finfo) {
c537d4
     struct tree *mtime = tree_child(finfo, s_mtime);
c537d4
@@ -217,9 +244,12 @@ static int filter_generate(struct tree *xfm, const char *root,
c537d4
 
c537d4
             if (strchr(e->value, SEP) == NULL)
c537d4
                 path = pathbase(path);
c537d4
-            if ((r = fnmatch(e->value, path, fnm_flags)) == 0) {
c537d4
+
c537d4
+            r = fnmatch_normalize(e->value, path, fnm_flags);
c537d4
+            if (r < 0)
c537d4
+                goto error;
c537d4
+            else if (r == 0)
c537d4
                 include = false;
c537d4
-            }
c537d4
         }
c537d4
 
c537d4
         if (include)
c537d4
@@ -254,7 +284,7 @@ static int filter_generate(struct tree *xfm, const char *root,
c537d4
 static int filter_matches(struct tree *xfm, const char *path) {
c537d4
     int found = 0;
c537d4
     list_for_each(f, xfm->children) {
c537d4
-        if (is_incl(f) && fnmatch(f->value, path, fnm_flags) == 0) {
c537d4
+        if (is_incl(f) && fnmatch_normalize(f->value, path, fnm_flags) == 0) {
c537d4
             found = 1;
c537d4
             break;
c537d4
         }
c537d4
@@ -262,7 +292,7 @@ static int filter_matches(struct tree *xfm, const char *path) {
c537d4
     if (! found)
c537d4
         return 0;
c537d4
     list_for_each(f, xfm->children) {
c537d4
-        if (is_excl(f) && (fnmatch(f->value, path, fnm_flags) == 0))
c537d4
+        if (is_excl(f) && (fnmatch_normalize(f->value, path, fnm_flags) == 0))
c537d4
             return 0;
c537d4
     }
c537d4
     return 1;
c537d4
diff --git a/tests/test-save.c b/tests/test-save.c
c537d4
index 04b86f7..617ef31 100644
c537d4
--- a/tests/test-save.c
c537d4
+++ b/tests/test-save.c
c537d4
@@ -183,6 +183,44 @@ static void testRelPath(CuTest *tc) {
c537d4
     CuAssertIntEquals(tc, 1, r);
c537d4
 }
c537d4
 
c537d4
+/* Check that loading and saving a file with // in the incl pattern works.
c537d4
+ * RHBZ#1031084
c537d4
+ */
c537d4
+static void testDoubleSlashPath(CuTest *tc) {
c537d4
+    int r;
c537d4
+
c537d4
+    r = aug_rm(aug, "/augeas/load/*");
c537d4
+    CuAssertPositive(tc, r);
c537d4
+
c537d4
+    r = aug_set(aug, "/augeas/load/Hosts/lens", "Hosts.lns");
c537d4
+    CuAssertRetSuccess(tc, r);
c537d4
+    r = aug_set(aug, "/augeas/load/Hosts/incl", "/etc//hosts");
c537d4
+    CuAssertRetSuccess(tc, r);
c537d4
+    r = aug_load(aug);
c537d4
+    CuAssertRetSuccess(tc, r);
c537d4
+
c537d4
+    r = aug_match(aug, "/files/etc/hosts/1/alias[ . = 'new']", NULL);
c537d4
+    CuAssertIntEquals(tc, 0, r);
c537d4
+
c537d4
+    r = aug_set(aug, "/files/etc/hosts/1/alias[last() + 1]", "new");
c537d4
+    CuAssertRetSuccess(tc, r);
c537d4
+
c537d4
+    r = aug_save(aug);
c537d4
+    CuAssertRetSuccess(tc, r);
c537d4
+    r = aug_match(aug, "/augeas//error", NULL);
c537d4
+    CuAssertIntEquals(tc, 0, r);
c537d4
+
c537d4
+    /* Force reloading the file */
c537d4
+    r = aug_rm(aug, "/augeas/files//mtime");
c537d4
+    CuAssertPositive(tc, r);
c537d4
+
c537d4
+    r = aug_load(aug);
c537d4
+    CuAssertRetSuccess(tc, r);
c537d4
+
c537d4
+    r = aug_match(aug, "/files/etc/hosts/1/alias[. = 'new']", NULL);
c537d4
+    CuAssertIntEquals(tc, 1, r);
c537d4
+}
c537d4
+
c537d4
 int main(void) {
c537d4
     char *output = NULL;
c537d4
     CuSuite* suite = CuSuiteNew();
c537d4
@@ -206,6 +244,7 @@ int main(void) {
c537d4
     SUITE_ADD_TEST(suite, testMultipleXfm);
c537d4
     SUITE_ADD_TEST(suite, testMtime);
c537d4
     SUITE_ADD_TEST(suite, testRelPath);
c537d4
+    SUITE_ADD_TEST(suite, testDoubleSlashPath);
c537d4
 
c537d4
     CuSuiteRun(suite);
c537d4
     CuSuiteSummary(suite, &output);
c537d4
-- 
c537d4
1.8.3.1
c537d4