From b81bfd6013ce871524e493272ac36b134f7fbbdf Mon Sep 17 00:00:00 2001
From: Nicolas Lacasse <nlacasse@google.com>
Date: Fri, 22 Mar 2019 17:37:10 -0700
Subject: lstat should resolve the final path component if it ends in a slash.

PiperOrigin-RevId: 239896221
Change-Id: I0949981fe50c57131c5631cdeb10b225648575c0
---
 test/syscalls/linux/stat.cc | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

(limited to 'test/syscalls')

diff --git a/test/syscalls/linux/stat.cc b/test/syscalls/linux/stat.cc
index 625392375..f96da5706 100644
--- a/test/syscalls/linux/stat.cc
+++ b/test/syscalls/linux/stat.cc
@@ -374,6 +374,31 @@ TEST_F(StatTest, ChildOfNonDir) {
   EXPECT_THAT(lstat(filename.c_str(), &st), SyscallFailsWithErrno(ENOTDIR));
 }
 
+// Test lstating a symlink directory.
+TEST_F(StatTest, LstatSymlinkDir) {
+  // Create a directory and symlink to it.
+  const auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
+  const std::string symlink_to_dir = NewTempAbsPath();
+  EXPECT_THAT(symlink(dir.path().c_str(), symlink_to_dir.c_str()),
+              SyscallSucceeds());
+  auto cleanup = Cleanup([&symlink_to_dir]() {
+    EXPECT_THAT(unlink(symlink_to_dir.c_str()), SyscallSucceeds());
+  });
+
+  // Lstat on the symlink should return symlink data.
+  struct stat st = {};
+  ASSERT_THAT(lstat(symlink_to_dir.c_str(), &st), SyscallSucceeds());
+  EXPECT_FALSE(S_ISDIR(st.st_mode));
+  EXPECT_TRUE(S_ISLNK(st.st_mode));
+
+  // Lstat on the symlink with a trailing slash should return the directory
+  // data.
+  ASSERT_THAT(lstat(absl::StrCat(symlink_to_dir, "/").c_str(), &st),
+              SyscallSucceeds());
+  EXPECT_TRUE(S_ISDIR(st.st_mode));
+  EXPECT_FALSE(S_ISLNK(st.st_mode));
+}
+
 // Verify that we get an ELOOP from too many symbolic links even when there
 // are directories in the middle.
 TEST_F(StatTest, LstatELOOPPath) {
-- 
cgit v1.2.3