Fix symlinks paths handling in abipkgdiff

When elements of an RPMs are referred to using a path that contains
symlinks, we need to resolve the symlinks in order to be able to
compare those paths.  We are not doing this fully and so we are
hitting corner cases where things break down in subtle ways.

This patch fixes that.

	* include/abg-tools-utils.h (real_path): Declare new function.
	* src/abg-tools-utils.cc (real_path): Define it.
	* tools/abipkgdiff.cc (package::convert_path_to_relative): Use the
	new real_path function to consider real path (where symlinks are
	resolved) of the extraction directory of the package.
	(get_interesting_files_under_dir): Similarly, use the new
	real_path function to consider the real path of the directory we
	are exploring.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2018-01-12 13:38:01 +01:00
parent d2c759c4d7
commit 3001e78a4f
3 changed files with 37 additions and 2 deletions

View File

@ -52,6 +52,7 @@ bool base_name(string const& path,
bool dir_name(string const &path,
string& path_dir_name,
bool keep_separator_at_end=false);
void real_path(const string&path, string& realpath);
bool ensure_dir_path_created(const string&);
bool ensure_parent_dir_created(const string&);
ostream& emit_prefix(const string& prog_name, ostream& out);

View File

@ -386,6 +386,28 @@ base_name(string const &path,
return true;
}
/// Return the real path of a given path.
///
/// The real path of path 'foo_path' is the same path as foo_path, but
/// with symlinks and relative paths resolved.
///
/// @param path the path to consider.
///
/// @param result the computed real_path;
void
real_path(const string&path, string& result)
{
if (path.empty())
{
result.clear();
return;
}
char *realp = realpath(path.c_str(), NULL);
if (realp)
result = realp;
}
/// Ensures #dir_path is a directory and is created. If #dir_path is
/// not created, this function creates it.
///

View File

@ -124,6 +124,7 @@ using abigail::tools_utils::ensure_dir_path_created;
using abigail::tools_utils::guess_file_type;
using abigail::tools_utils::string_ends_with;
using abigail::tools_utils::dir_name;
using abigail::tools_utils::real_path;
using abigail::tools_utils::string_suffix;
using abigail::tools_utils::sorted_strings_common_prefix;
using abigail::tools_utils::file_type;
@ -592,7 +593,13 @@ public:
/// the extracted directory.
bool
convert_path_to_relative(const string& path, string& converted_path) const
{return string_suffix(path, extracted_dir_path(), converted_path);}
{
string root = extracted_dir_path_;
real_path(root, root);
string p = path;
real_path(p, p);
return string_suffix(p, root, converted_path);
}
// Convert the absolute path of an element of this package into a
// path relative to the prefix common to the paths of all elements
@ -1832,7 +1839,12 @@ get_interesting_files_under_dir(const string dir,
vector<string>& interesting_files)
{
bool is_ok = false;
char* paths[] = {const_cast<char*>(dir.c_str()), 0};
string root;
real_path(dir, root);
if (root.empty())
root = dir;
char* paths[] = {const_cast<char*>(root.c_str()), 0};
FTS *file_hierarchy = fts_open(paths, FTS_LOGICAL|FTS_NOCHDIR, NULL);
if (!file_hierarchy)