Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #3447 from Karlson2k/win32_fix_relative_paths

[Win32] fix relative paths, fixes #14812
  • Loading branch information...
commit 19847d58258db0ebfc4f138d445013a714c33bf0 2 parents 0c04283 + d0e790b
@jmarshallnz jmarshallnz authored
View
13 xbmc/filesystem/windows/WINSMBDirectory.cpp
@@ -95,14 +95,11 @@ bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &i
memset(&wfd, 0, sizeof(wfd));
//rebuild the URL
- std::string strUNCShare = "\\\\?\\UNC\\" + (std::string)url.GetHostName() + "\\" + URIUtils::FixSlashesAndDups(url.GetFileName(), '\\');
-
- if(!URIUtils::HasSlashAtEnd(strUNCShare))
- strUNCShare.append("\\");
-
- std::wstring strSearchMask;
- g_charsetConverter.utf8ToW(strUNCShare, strSearchMask, false, false, true);
- strSearchMask += L"*";
+ std::wstring strSearchMask(CWIN32Util::ConvertPathToWin32Form(GetLocal(strPath)));
+ if (!strSearchMask.empty() && strSearchMask[strSearchMask.length() - 1] == '\\')
+ strSearchMask += L'*';
+ else
+ strSearchMask += L"\\*";
FILETIME localTime;
CAutoPtrFind hFind ( FindFirstFileW(strSearchMask.c_str(), &wfd));
View
33 xbmc/utils/URIUtils.cpp
@@ -1059,6 +1059,39 @@ std::string URIUtils::FixSlashesAndDups(const std::string& path, const char slas
}
+std::string URIUtils::CanonicalizePath(const std::string& path, const char slashCharacter /*= '\\'*/)
+{
+ assert(slashCharacter == '\\' || slashCharacter == '/');
+
+ if (path.empty())
+ return path;
+
+ const std::string slashStr(1, slashCharacter);
+ vector<std::string> pathVec, resultVec;
+ StringUtils::Tokenize(path, pathVec, slashStr);
+
+ for (vector<std::string>::const_iterator it = pathVec.begin(); it != pathVec.end(); ++it)
+ {
+ if (*it == ".")
+ { /* skip - do nothing */ }
+ else if (*it == ".." && !resultVec.empty() && resultVec.back() != "..")
+ resultVec.pop_back();
+ else
+ resultVec.push_back(*it);
+ }
+
+ std::string result;
+ if (path[0] == slashCharacter)
+ result.push_back(slashCharacter); // add slash at the begin
+
+ result += StringUtils::Join(resultVec, slashStr);
+
+ if (path[path.length() - 1] == slashCharacter && !result.empty() && result[result.length() - 1] != slashCharacter)
+ result.push_back(slashCharacter); // add slash at the end if result isn't empty and result isn't "/"
+
+ return result;
+}
+
CStdString URIUtils::AddFileToFolder(const CStdString& strFolder,
const CStdString& strFile)
{
View
12 xbmc/utils/URIUtils.h
@@ -132,6 +132,18 @@ class URIUtils
static void RemoveSlashAtEnd(std::string& strFolder);
static bool CompareWithoutSlashAtEnd(const CStdString& strPath1, const CStdString& strPath2);
static std::string FixSlashesAndDups(const std::string& path, const char slashCharacter = '/', const size_t startFrom = 0);
+ /**
+ * Convert path to form without duplicated slashes and without relative directories
+ * Strip duplicated slashes
+ * Resolve and remove relative directories ("/../" and "/./")
+ * Will ignore slashes with other direction than specified
+ * Will not resolve path starting from relative directory
+ * @warning Don't use with "protocol://path"-style URLs
+ * @param path string to process
+ * @param slashCharacter character to use as directory delimiter
+ * @return transformed path
+ */
+ static std::string CanonicalizePath(const std::string& path, const char slashCharacter = '\\');
static void CreateArchivePath(CStdString& strUrlPath,
const CStdString& strType,
View
21 xbmc/win32/WIN32Util.cpp
@@ -481,20 +481,25 @@ std::wstring CWIN32Util::ConvertPathToWin32Form(const std::string& pathUtf8)
if (pathUtf8.compare(0, 2, "\\\\", 2) != 0) // pathUtf8 don't start from "\\"
{ // assume local file path in form 'C:\Folder\File.ext'
std::string formedPath("\\\\?\\"); // insert "\\?\" prefix
- formedPath += URIUtils::FixSlashesAndDups(pathUtf8, '\\'); // fix duplicated and forward slashes
+ formedPath += URIUtils::CanonicalizePath(URIUtils::FixSlashesAndDups(pathUtf8, '\\'), '\\'); // fix duplicated and forward slashes, resolve relative path
convertResult = g_charsetConverter.utf8ToW(formedPath, result, false, false, true);
}
-
else if (pathUtf8.compare(0, 8, "\\\\?\\UNC\\", 8) == 0) // pathUtf8 starts from "\\?\UNC\"
- convertResult = g_charsetConverter.utf8ToW(URIUtils::FixSlashesAndDups(pathUtf8, '\\', 7), result, false, false, true); // fix duplicated and forward slashes, don't touch "\\?\UNC" prefix
-
+ {
+ std::string formedPath("\\\\?\\UNC"); // start from "\\?\UNC" prefix
+ formedPath += URIUtils::CanonicalizePath(URIUtils::FixSlashesAndDups(pathUtf8.substr(7), '\\'), '\\'); // fix duplicated and forward slashes, resolve relative path, don't touch "\\?\UNC" prefix,
+ convertResult = g_charsetConverter.utf8ToW(formedPath, result, false, false, true);
+ }
else if (pathUtf8.compare(0, 4, "\\\\?\\", 4) == 0) // pathUtf8 starts from "\\?\", but it's not UNC path
- convertResult = g_charsetConverter.utf8ToW(URIUtils::FixSlashesAndDups(pathUtf8, '\\', 4), result, false, false, true); // fix duplicated and forward slashes, don't touch "\\?\" prefix
-
+ {
+ std::string formedPath("\\\\?"); // start from "\\?" prefix
+ formedPath += URIUtils::CanonicalizePath(URIUtils::FixSlashesAndDups(pathUtf8.substr(3), '\\'), '\\'); // fix duplicated and forward slashes, resolve relative path, don't touch "\\?" prefix,
+ convertResult = g_charsetConverter.utf8ToW(formedPath, result, false, false, true);
+ }
else // pathUtf8 starts from "\\", but not from "\\?\UNC\"
{ // assume UNC path in form '\\server\share\folder\file.ext'
- std::string formedPath("\\\\?\\UNC\\"); // append "\\?\UNC\" prefix
- formedPath.append(URIUtils::FixSlashesAndDups(pathUtf8, '\\', 2), 2, std::string::npos); // fix duplicated and forward slashes, skip and cut out two first slashes
+ std::string formedPath("\\\\?\\UNC"); // append "\\?\UNC" prefix
+ formedPath += URIUtils::CanonicalizePath(URIUtils::FixSlashesAndDups(pathUtf8), '\\'); // fix duplicated and forward slashes, resolve relative path, transform "\\" prefix to single "\"
convertResult = g_charsetConverter.utf8ToW(formedPath, result, false, false, true);
}
Please sign in to comment.
Something went wrong with that request. Please try again.