How to properly escape weird characters in paths to have a valid filelist?

Miro Hrončok mhroncok at
Tue Jun 29 11:32:13 UTC 2021


we have a filelist generator and recently I've discovered a bug when the path 
contains a space. Our generator generates one path fer line in a text file that 
is to be used via %file -f.

Suppose the path is:

/usr/share/data/filename with spaces in it

In that case, when we literally include this line in the filelist, RPM says 
that "with", "spaces", "in" and "it" does not start with "/".

Quite easily I was able to find out that we need to write the path like this:

"/usr/share/data/filename with spaces in it"

That works, so I was about to write a function (in Python) that puts the entire 
path in "double quotes" if it contains some space characters (spaces, new 
lines, etc.).

However, I have trouble figuring out how to properly escape a path like this:

/usr/share/data/filename with spaces and "quotes" in it

I've tried the following options with no luck:

'/usr/share/data/filename with spaces and "quotes" in it'
"/usr/share/data/filename with spaces and \"quotes\" in it"
"/usr/share/data/filename with spaces and \\"quotes\\" in it"
"/usr/share/data/filename with spaces and \\\"quotes\\\" in it"

While at it, I've also tried to figure out how to escape a % symbol in path. 
Suppose the path is literally:


I've tried the following options with no luck:

/usr/share/data/%%%%%version ...

This is my function so far, but it is quite incomplete:

import string

def escape_rpm_path(path):
     Escape special characters in paths
     E.g. a space in path otherwise makes RPM think it's multiple paths,
     unless we put it in "quotes".
     Or a literal % symbol in path might be expanded as a macro if not escaped.
     if "%" in path:
         # path = path.replace("%", "%%") is not enough
         raise NotImplementedError("% symbol in paths, dunno")

     if any(symbol in path for symbol in string.whitespace):
         if '"' in path:
             raise NotImplementedError('" symbol in path with spaces, dunno')
         return f'"{path}"'

     # I wish all paths in the world would end up here:
     return path

What do I do? Is there a specification for the filelist syntax somewhere?

Miro Hrončok
Phone: +420777974800
IRC: mhroncok

More information about the Rpm-list mailing list