summaryrefslogtreecommitdiff
path: root/rpmio/rpmfileutil.c
diff options
context:
space:
mode:
authorMichal Domonkos <mdomonko@redhat.com>2022-04-19 16:50:21 +0200
committerPanu Matilainen <pmatilai@redhat.com>2022-10-04 10:11:32 +0300
commitd44114f007f54f205ffa13d22724199fe50a137a (patch)
tree54a1f1330581e23cb714341ff597745fea824650 /rpmio/rpmfileutil.c
parent055734eb2a0f9fe4dd275c71288cd61828d26f81 (diff)
downloadrpm-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.c16
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;