AU: When checking if we've visited a file before, don't follow symlinks.
A bug caused a failure when a file existed on the old image that was a
symlink to a non-existent path. This CL fixes that bug.
BUG=chromium-os:12393
TEST=unittests/generated and tested a delta
Change-Id: Ifba711be2bfc3c1d96a4ed8536b16b5d7b8a0cae
Review URL: http://codereview.chromium.org/6551015
diff --git a/delta_diff_generator.cc b/delta_diff_generator.cc
index ccdf27a..a500054 100644
--- a/delta_diff_generator.cc
+++ b/delta_diff_generator.cc
@@ -149,6 +149,7 @@
for (FilesystemIterator fs_iter(new_root,
utils::SetWithValue<string>("/lost+found"));
!fs_iter.IsEnd(); fs_iter.Increment()) {
+ // We never diff symlinks (here, we check that dst file is not a symlink).
if (!S_ISREG(fs_iter.GetStat().st_mode))
continue;
@@ -169,11 +170,12 @@
// from using a graph/cycle detection/etc to generate diffs, and at that
// time, it will be easy (non-complex) to have many operations read
// from the same source blocks. At that time, this code can die. -adlr
- bool should_diff_from_source = true;
+ bool should_diff_from_source = false;
string src_path = old_root + fs_iter.GetPartialPath();
- if (utils::FileExists(src_path.c_str())) {
- struct stat src_stbuf;
- TEST_AND_RETURN_FALSE_ERRNO(0 == stat(src_path.c_str(), &src_stbuf));
+ struct stat src_stbuf;
+ // We never diff symlinks (here, we check that src file is not a symlink).
+ if (0 == lstat(src_path.c_str(), &src_stbuf) &&
+ S_ISREG(src_stbuf.st_mode)) {
should_diff_from_source = !utils::SetContainsKey(visited_src_inodes,
src_stbuf.st_ino);
visited_src_inodes.insert(src_stbuf.st_ino);