diff options
author | Michal Domonkos <mdomonko@redhat.com> | 2022-05-23 14:37:54 +0200 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2022-06-27 08:42:36 +0300 |
commit | 9e541c6a7da076bc1c1beb1ee45fd5fdd735358c (patch) | |
tree | 87ce224c6934a8c7961ef2adf2c9857ddc52be05 /rpmio/rpmglob.c | |
parent | 321933f060896f721e361a1c8a8d3731bdcee827 (diff) | |
download | rpm-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.c | 38 |
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); } |