summaryrefslogtreecommitdiff
path: root/rpmio/rpmglob.c
diff options
context:
space:
mode:
authorMichal Domonkos <mdomonko@redhat.com>2022-05-23 14:37:54 +0200
committerPanu Matilainen <pmatilai@redhat.com>2022-06-27 08:42:36 +0300
commit9e541c6a7da076bc1c1beb1ee45fd5fdd735358c (patch)
tree87ce224c6934a8c7961ef2adf2c9857ddc52be05 /rpmio/rpmglob.c
parent321933f060896f721e361a1c8a8d3731bdcee827 (diff)
downloadrpm-9e541c6a7da076bc1c1beb1ee45fd5fdd735358c.tar.gz
Fix rpmGlob() escape support
We currently accept a space-separated list of patterns here so any backslash, whether it belongs to a space char or not, gets consumed by poptParseArgvString() before the string is passed to glob(3), requiring callers to double-escape anything they wish to keep literal. Fix that by only accepting one pattern. Adapt the one caller which relies on this actually being a list, in rpmReadPackageManifest(), and those callers where we preserve spaces by escaping them which is no longer needed. Replace our own heuristic emulating GLOB_NOMAGIC with the actual flag to glob(3) so that literal (double) backslashes are also handled properly. Keep the indentation of the original for loop to make the diff easier to read, next commit will fix that. No immediate effect within RPM since we currently avoid passing escaped patterns to rpmGlob(), this is just a prerequisite for the following commits. External users of rpmGlob(), as unlikely as they are, might, in theory, notice this subtle change but we'll be bumping the soname in 4.19 so that's covered.
Diffstat (limited to 'rpmio/rpmglob.c')
-rw-r--r--rpmio/rpmglob.c38
1 files changed, 14 insertions, 24 deletions
diff --git a/rpmio/rpmglob.c b/rpmio/rpmglob.c
index 7dbc34185..2e0c6c35c 100644
--- a/rpmio/rpmglob.c
+++ b/rpmio/rpmglob.c
@@ -28,7 +28,6 @@
#include <fnmatch.h>
#include <glob.h>
-#include <popt.h>
#include <rpm/rpmfileutil.h>
#include <rpm/rpmurl.h>
@@ -85,34 +84,27 @@ static int __glob_pattern_p(const char *pattern, int quote)
/* librpmio exported interfaces */
-int rpmGlob(const char * patterns, int * argcPtr, ARGV_t * argvPtr)
+int rpmGlob(const char * pattern, int * argcPtr, ARGV_t * argvPtr)
{
- int ac = 0;
- const char ** av = NULL;
int argc = 0;
ARGV_t argv = NULL;
char * globRoot = NULL;
const char *home = getenv("HOME");
- int gflags = 0;
+ int gflags = GLOB_NOMAGIC;
#ifdef ENABLE_NLS
char * old_collate = NULL;
char * old_ctype = NULL;
const char * t;
#endif
size_t maxb, nb;
- int i, j;
- int rc;
+ int i;
+ int rc = 0;
gflags |= GLOB_BRACE;
if (home != NULL && strlen(home) > 0)
gflags |= GLOB_TILDE;
- /* Can't use argvSplit() here, it doesn't handle whitespace etc escapes */
- rc = poptParseArgvString(patterns, &ac, &av);
- if (rc)
- return rc;
-
#ifdef ENABLE_NLS
t = setlocale(LC_COLLATE, NULL);
if (t)
@@ -124,20 +116,19 @@ int rpmGlob(const char * patterns, int * argcPtr, ARGV_t * argvPtr)
(void) setlocale(LC_CTYPE, "C");
#endif
- if (av != NULL)
- for (j = 0; j < ac; j++) {
+ if (1) {
char * globURL;
const char * path;
- int ut = urlPath(av[j], &path);
+ int ut = urlPath(pattern, &path);
int local = (ut == URL_IS_PATH) || (ut == URL_IS_UNKNOWN);
size_t plen = strlen(path);
int flags = gflags;
int dir_only = (plen > 0 && path[plen-1] == '/');
glob_t gl;
- if (!local || (!rpmIsGlob(av[j], 0) && strchr(path, '~') == NULL)) {
- argvAdd(&argv, av[j]);
- continue;
+ if (!local) {
+ argvAdd(&argv, pattern);
+ goto exit;
}
if (dir_only)
@@ -146,7 +137,7 @@ int rpmGlob(const char * patterns, int * argcPtr, ARGV_t * argvPtr)
gl.gl_pathc = 0;
gl.gl_pathv = NULL;
- rc = glob(av[j], flags, NULL, &gl);
+ rc = glob(pattern, flags, NULL, &gl);
if (rc)
goto exit;
@@ -157,7 +148,7 @@ int rpmGlob(const char * patterns, int * argcPtr, ARGV_t * argvPtr)
maxb = nb;
}
- nb = ((ut == URL_IS_PATH) ? (path - av[j]) : 0);
+ nb = ((ut == URL_IS_PATH) ? (path - pattern) : 0);
maxb += nb;
maxb += 1;
globURL = globRoot = xmalloc(maxb);
@@ -165,7 +156,7 @@ int rpmGlob(const char * patterns, int * argcPtr, ARGV_t * argvPtr)
switch (ut) {
case URL_IS_PATH:
case URL_IS_DASH:
- strncpy(globRoot, av[j], nb);
+ strncpy(globRoot, pattern, nb);
break;
case URL_IS_HTTPS:
case URL_IS_HTTP:
@@ -196,6 +187,7 @@ int rpmGlob(const char * patterns, int * argcPtr, ARGV_t * argvPtr)
free(globURL);
}
+exit:
argc = argvCount(argv);
if (argc > 0) {
if (argvPtr)
@@ -203,11 +195,10 @@ int rpmGlob(const char * patterns, int * argcPtr, ARGV_t * argvPtr)
if (argcPtr)
*argcPtr = argc;
rc = 0;
- } else
+ } else if (rc == 0)
rc = 1;
-exit:
#ifdef ENABLE_NLS
if (old_collate) {
(void) setlocale(LC_COLLATE, old_collate);
@@ -218,7 +209,6 @@ exit:
free(old_ctype);
}
#endif
- av = _free(av);
if (rc || argvPtr == NULL) {
argvFree(argv);
}