Fix crash for getSHA1(./hello)

Summary:
getSHA1 is only handling std::system_error. If another kind of exception is thrown, it's never caught and edenfs crashes.

Calling EdenMount::getInode with a path such as "./hello" will cause a std::domain_error to be thrown. Since std::domain_error is not derived from std::system_error, `getSHA1ForPathDefensively(["./hello"])` crashes edenfs.

Fix the crash by forwarding all exceptions over Thrift, not just std::system_error-s.

Reviewed By: simpkins

Differential Revision: D13386450

fbshipit-source-id: 06262dad30a5508ed482c9e8979b61aa9643280a
This commit is contained in:
Matt Glazar 2018-12-07 16:32:35 -08:00 committed by Facebook Github Bot
parent 4ca24ee2b3
commit f33c394da5
2 changed files with 9 additions and 7 deletions

View File

@ -375,13 +375,8 @@ Future<Hash> EdenServiceHandler::getSHA1ForPathDefensively(
StringPiece mountPoint,
StringPiece path) noexcept {
#ifndef EDEN_WIN
// Calls getSHA1ForPath() and traps all immediate exceptions and converts
// them in to a Future result.
try {
return getSHA1ForPath(mountPoint, path);
} catch (const std::system_error& e) {
return makeFuture<Hash>(newEdenError(e));
}
return folly::makeFutureWith(
[&] { return getSHA1ForPath(mountPoint, path); });
#else
NOT_IMPLEMENTED();
#endif // !EDEN_WIN

View File

@ -75,6 +75,13 @@ class ThriftTest(testcase.EdenRepoTest):
self.client.getSHA1(self.mount_path_bytes, [b"hello", b"adir/file"]),
)
def test_get_sha1_throws_for_path_with_dot_components(self) -> None:
results = self.client.getSHA1(self.mount_path_bytes, [b"./hello"])
self.assertEqual(1, len(results))
self.assert_error(
results[0], "std::domain_error: PathComponent must not be . or .."
)
def test_get_sha1_throws_for_empty_string(self) -> None:
results = self.client.getSHA1(self.mount_path_bytes, [b""])
self.assertEqual(1, len(results))