diff options
author | Michal Domonkos <mdomonko@redhat.com> | 2022-04-19 16:50:21 +0200 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2022-10-04 10:11:32 +0300 |
commit | d44114f007f54f205ffa13d22724199fe50a137a (patch) | |
tree | 54a1f1330581e23cb714341ff597745fea824650 /rpmio/rpmfileutil.c | |
parent | 055734eb2a0f9fe4dd275c71288cd61828d26f81 (diff) | |
download | rpm-d44114f007f54f205ffa13d22724199fe50a137a.tar.gz |
Preserve literal value of quoted paths in %files
Turn off the special meaning of metacharacters within a filename
enclosed in quotes, just like a typical shell does it.
Do it by automatically escaping such chars at parse time, as that
internally reduces the case to the one where the spec author does the
escaping manually (i.e. fewer code paths to worry about). This will
also allow us to implement partial quoting (e.g. /foo"*") in the future
if we so choose. Currently, only fully quoted filenames are supported.
This is an extension of the original (and possibly misleading) quotation
semantics that was only meant for whitespace escaping. It's backward
compatible since globs never worked correctly when used in a quoted
filename anyway, due to rpmGlob() splitting them by whitespace and
globbing the parts separately. This was only fixed recently in commit
4030062f2bf16d7a4540c78c1e61706f3810fe9b but hasn't yet been released,
so no spec files in production are really expected to be using such
filenames.
Make the newly added rpmEscapeChars() accept either a string of chars to
escape or a function, with the latter allowing the use of isspace(3)
which is locale-dependent in rpmEscapeSpaces(). For ease of use, expose
the string variant as rpmEscape(), though.
Diffstat (limited to 'rpmio/rpmfileutil.c')
-rw-r--r-- | rpmio/rpmfileutil.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/rpmio/rpmfileutil.c b/rpmio/rpmfileutil.c index bcb61d105..c4350b2f6 100644 --- a/rpmio/rpmfileutil.c +++ b/rpmio/rpmfileutil.c @@ -380,7 +380,7 @@ char * rpmGetPath(const char *path, ...) return rpmCleanPath(res); } -char * rpmEscapeSpaces(const char * s) +static char * rpmEscapeChars(const char *s, const char *accept, int (*fn)(int)) { const char * se; char * t; @@ -388,7 +388,7 @@ char * rpmEscapeSpaces(const char * s) size_t nb = 0; for (se = s; *se; se++) { - if (isspace(*se)) + if ((accept && strchr(accept, *se)) || (fn && fn(*se))) nb++; nb++; } @@ -396,7 +396,7 @@ char * rpmEscapeSpaces(const char * s) t = te = xmalloc(nb); for (se = s; *se; se++) { - if (isspace(*se)) + if ((accept && strchr(accept, *se)) || (fn && fn(*se))) *te++ = '\\'; *te++ = *se; } @@ -404,6 +404,16 @@ char * rpmEscapeSpaces(const char * s) return t; } +char * rpmEscapeSpaces(const char *s) +{ + return rpmEscapeChars(s, NULL, isspace); +} + +char * rpmEscape(const char *s, const char *accept) +{ + return rpmEscapeChars(s, accept, NULL); +} + void rpmUnescape(char *s, const char *accept) { char *p, *q; |