App: handle symlinks in Application::processFiles & DocInfo::getDocPath

This commit is contained in:
captain0xff
2026-01-26 18:15:28 +05:30
committed by Max Wilfinger
parent a4a1ef7294
commit 79632dd3c6
4 changed files with 53 additions and 2 deletions

View File

@@ -925,7 +925,7 @@ Document* Application::openDocumentPrivate(const char * FileName,
if (!File.exists()) {
std::stringstream str;
str << "File '" << FileName << "' does not exist!";
throw Base::FileSystemError(str.str().c_str());
throw Base::FileSystemError(str.str());
}
// Before creating a new document we check whether the document is already open
@@ -2803,7 +2803,18 @@ std::list<std::string> Application::processFiles(const std::list<std::string>& f
std::list<std::string> processed;
Base::Console().log("Init: Processing command line files\n");
for (const auto & it : files) {
Base::FileInfo file(it);
// Can we safely remove the isSymlink check and directly query the canonical
// path for every string? The reason for avoiding it currently is that
// getCannonicalPath will log an error if the file doesn't exist
if (file.isSymlink()) {
if (auto cannonicalPath = file.getCannonicalPath()) {
file = Base::FileInfo(*cannonicalPath);
} else {
Base::Console().error("Failed to process symlink file: %s\n", file.filePath());
}
}
Base::Console().log("Init: Processing file: %s\n",file.filePath().c_str());

View File

@@ -3349,7 +3349,8 @@ public:
throw Base::RuntimeError("Owner document not saved");
}
QDir docDir(QFileInfo(QString::fromUtf8(docPath)).absoluteDir());
QFileInfo docFileInfo{QString::fromUtf8(docPath)};
QDir docDir(docFileInfo.canonicalPath());
if (!absolute) {
path = QDir::cleanPath(docDir.absoluteFilePath(path));
if (fullPath) {

View File

@@ -425,6 +425,16 @@ bool FileInfo::isDir() const
return false;
}
bool FileInfo::isSymlink() const
{
fs::path path = stringToPath(FileName);
if (fs::exists(path)) {
return fs::is_symlink(path);
}
return false;
}
unsigned int FileInfo::size() const
{
unsigned int bytes {};
@@ -566,3 +576,24 @@ std::vector<Base::FileInfo> FileInfo::getDirectoryContent() const
return list;
}
std::optional<std::string> FileInfo::getSymlinkTarget()
{
fs::path path = stringToPath(FileName);
if (isSymlink()) {
return pathToString(fs::read_symlink(path));
}
return std::nullopt;
}
std::optional<std::string> FileInfo::getCannonicalPath()
{
try {
fs::path path = stringToPath(FileName);
return pathToString(fs::canonical(path));
}
catch (const fs::filesystem_error& e) {
std::clog << e.what() << '\n';
return std::nullopt;
}
}

View File

@@ -30,6 +30,7 @@
#include <filesystem>
#include <string>
#include <vector>
#include <optional>
#include <FCGlobal.h>
@@ -125,6 +126,8 @@ public:
bool isFile() const;
/// Checks if it is a directory (not a file)
bool isDir() const;
/// Checks if it is a symbolic link (returns false if the file doesn't exist)
bool isSymlink() const;
/// The size of the file
unsigned int size() const;
/// Returns the time when the file was last modified.
@@ -153,6 +156,11 @@ public:
/// Rename the file
bool copyTo(const char* NewName) const;
/// Returns the folder or directory the symlink points
std::optional<std::string> getSymlinkTarget();
/// Returns the absolute path without any "..", "." or symlinks
std::optional<std::string> getCannonicalPath();
/** @name Tools */
//@{
/// Get a unique File Name in the given or (if 0) in the temp path