Lubos Kardos ee316a
From d14ecfe587efbe80e5534161dbd3a4f7158b4e2b Mon Sep 17 00:00:00 2001
Lubos Kardos ee316a
From: Lubos Kardos <lkardos@redhat.com>
Lubos Kardos ee316a
Date: Mon, 27 Jul 2015 11:22:19 +0200
Lubos Kardos ee316a
Subject: [PATCH] Enable {} expansion in rpmGlob() (rhbz:1246743)
Lubos Kardos ee316a
Lubos Kardos ee316a
---
Lubos Kardos ee316a
 rpmio/rpmglob.c | 42 ++++++++++++++++++++++++++++++++----------
Lubos Kardos ee316a
 1 file changed, 32 insertions(+), 10 deletions(-)
Lubos Kardos ee316a
Lubos Kardos ee316a
diff --git a/rpmio/rpmglob.c b/rpmio/rpmglob.c
Lubos Kardos ee316a
index 4fc106d..597ac5c 100644
Lubos Kardos ee316a
--- a/rpmio/rpmglob.c
Lubos Kardos ee316a
+++ b/rpmio/rpmglob.c
Lubos Kardos ee316a
@@ -150,7 +150,7 @@ static inline const char *next_brace_sub(const char *begin)
Lubos Kardos ee316a
     return cp;
Lubos Kardos ee316a
 }
Lubos Kardos ee316a
 
Lubos Kardos ee316a
-static int __glob_pattern_p(const char *pattern, int quote);
Lubos Kardos ee316a
+static int __glob_pattern_p(const char *pattern, int flags);
Lubos Kardos ee316a
 
Lubos Kardos ee316a
 /* Do glob searching for PATTERN, placing results in PGLOB.
Lubos Kardos ee316a
    The bits defined above may be set in FLAGS.
Lubos Kardos ee316a
@@ -419,7 +419,7 @@ glob(const char *pattern, int flags,
Lubos Kardos ee316a
 	return GLOB_NOMATCH;
Lubos Kardos ee316a
     }
Lubos Kardos ee316a
 
Lubos Kardos ee316a
-    if (__glob_pattern_p(dirname, !(flags & GLOB_NOESCAPE))) {
Lubos Kardos ee316a
+    if (__glob_pattern_p(dirname, flags)) {
Lubos Kardos ee316a
 	/* The directory name contains metacharacters, so we
Lubos Kardos ee316a
 	   have to glob for the directory, and then glob for
Lubos Kardos ee316a
 	   the pattern in each directory found.  */
Lubos Kardos ee316a
@@ -646,10 +646,11 @@ static int prefix_array(const char *dirname, char **array, size_t n)
Lubos Kardos ee316a
 
Lubos Kardos ee316a
 /* Return nonzero if PATTERN contains any metacharacters.
Lubos Kardos ee316a
    Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
Lubos Kardos ee316a
-static int __glob_pattern_p(const char *pattern, int quote)
Lubos Kardos ee316a
+static int __glob_pattern_p(const char *pattern, int flags)
Lubos Kardos ee316a
 {
Lubos Kardos ee316a
     register const char *p;
Lubos Kardos ee316a
-    int open = 0;
Lubos Kardos ee316a
+    int openBrackets = 0;
Lubos Kardos ee316a
+    int openBraces = 0;
Lubos Kardos ee316a
 
Lubos Kardos ee316a
     for (p = pattern; *p != '\0'; ++p)
Lubos Kardos ee316a
 	switch (*p) {
Lubos Kardos ee316a
@@ -658,18 +659,29 @@ static int __glob_pattern_p(const char *pattern, int quote)
Lubos Kardos ee316a
 	    return 1;
Lubos Kardos ee316a
 
Lubos Kardos ee316a
 	case '\\':
Lubos Kardos ee316a
-	    if (quote && p[1] != '\0')
Lubos Kardos ee316a
+	    if (!(flags & GLOB_NOESCAPE) && p[1] != '\0')
Lubos Kardos ee316a
 		++p;
Lubos Kardos ee316a
 	    break;
Lubos Kardos ee316a
 
Lubos Kardos ee316a
 	case '[':
Lubos Kardos ee316a
-	    open = 1;
Lubos Kardos ee316a
+	    openBrackets = 1;
Lubos Kardos ee316a
 	    break;
Lubos Kardos ee316a
 
Lubos Kardos ee316a
 	case ']':
Lubos Kardos ee316a
-	    if (open)
Lubos Kardos ee316a
+	    if (openBrackets)
Lubos Kardos ee316a
 		return 1;
Lubos Kardos ee316a
 	    break;
Lubos Kardos ee316a
+
Lubos Kardos ee316a
+	case '{':
Lubos Kardos ee316a
+	    if (flags & GLOB_BRACE)
Lubos Kardos ee316a
+		openBraces = 1;
Lubos Kardos ee316a
+	    break;
Lubos Kardos ee316a
+
Lubos Kardos ee316a
+	case '}':
Lubos Kardos ee316a
+	    if (openBraces)
Lubos Kardos ee316a
+		return 1;
Lubos Kardos ee316a
+	    break;
Lubos Kardos ee316a
+
Lubos Kardos ee316a
 	}
Lubos Kardos ee316a
 
Lubos Kardos ee316a
     return 0;
Lubos Kardos ee316a
@@ -694,7 +706,7 @@ glob_in_dir(const char *pattern, const char *directory, int flags,
Lubos Kardos ee316a
     int meta;
Lubos Kardos ee316a
     int save;
Lubos Kardos ee316a
 
Lubos Kardos ee316a
-    meta = __glob_pattern_p(pattern, !(flags & GLOB_NOESCAPE));
Lubos Kardos ee316a
+    meta = __glob_pattern_p(pattern, flags);
Lubos Kardos ee316a
     if (meta == 0) {
Lubos Kardos ee316a
 	if (flags & (GLOB_NOCHECK | GLOB_NOMAGIC))
Lubos Kardos ee316a
 	    /* We need not do any tests.  The PATTERN contains no meta
Lubos Kardos ee316a
@@ -844,6 +856,8 @@ int rpmGlob(const char * patterns, int * argcPtr, ARGV_t * argvPtr)
Lubos Kardos ee316a
     int i, j;
Lubos Kardos ee316a
     int rc;
Lubos Kardos ee316a
 
Lubos Kardos ee316a
+    gflags |= GLOB_BRACE;
Lubos Kardos ee316a
+
Lubos Kardos ee316a
     if (home != NULL && strlen(home) > 0) 
Lubos Kardos ee316a
 	gflags |= GLOB_TILDE;
Lubos Kardos ee316a
 
Lubos Kardos ee316a
@@ -874,7 +888,9 @@ int rpmGlob(const char * patterns, int * argcPtr, ARGV_t * argvPtr)
Lubos Kardos ee316a
 	int dir_only = (plen > 0 && path[plen-1] == '/');
Lubos Kardos ee316a
 	glob_t gl;
Lubos Kardos ee316a
 
Lubos Kardos ee316a
-	if (!local || (!rpmIsGlob(av[j], 0) && strchr(path, '~') == NULL)) {
Lubos Kardos ee316a
+	if (!local || (!rpmIsGlob(av[j], GLOB_NOESCAPE | flags) &&
Lubos Kardos ee316a
+	    strchr(path, '~') == NULL)) {
Lubos Kardos ee316a
+
Lubos Kardos ee316a
 	    argvAdd(&argv, av[j]);
Lubos Kardos ee316a
 	    continue;
Lubos Kardos ee316a
 	}
Lubos Kardos ee316a
@@ -966,5 +982,11 @@ exit:
Lubos Kardos ee316a
 
Lubos Kardos ee316a
 int rpmIsGlob(const char * pattern, int quote)
Lubos Kardos ee316a
 {
Lubos Kardos ee316a
-    return __glob_pattern_p(pattern, quote);
Lubos Kardos ee316a
+    int flags = 0;
Lubos Kardos ee316a
+    if (!quote) {
Lubos Kardos ee316a
+	flags |= GLOB_NOESCAPE;
Lubos Kardos ee316a
+    }
Lubos Kardos ee316a
+    flags |= GLOB_BRACE;
Lubos Kardos ee316a
+
Lubos Kardos ee316a
+    return __glob_pattern_p(pattern, flags);
Lubos Kardos ee316a
 }
Lubos Kardos ee316a
-- 
Lubos Kardos ee316a
1.9.3
Lubos Kardos ee316a