Skip to content

Commit

Permalink
fixed: Handle (non) URL encoding and forward backward slashes properl…
Browse files Browse the repository at this point in the history
…y for path substitution
  • Loading branch information
arnova committed Jan 5, 2014
1 parent 6ea5b07 commit 4cad814
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 12 deletions.
75 changes: 63 additions & 12 deletions xbmc/utils/URIUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,29 +395,80 @@ bool URIUtils::GetParentPath(const CStdString& strPath, CStdString& strParent)
return true;
}

std::string URLEncodePath(const std::string& strPath)
{
vector<string> segments = StringUtils::Split(strPath, "/");
for (vector<string>::iterator i = segments.begin(); i != segments.end(); ++i)
*i = CURL::Encode(*i);

return StringUtils::Join(segments, "/");
}

std::string URLDecodePath(const std::string& strPath)
{
vector<string> segments = StringUtils::Split(strPath, "/");
for (vector<string>::iterator i = segments.begin(); i != segments.end(); ++i)
*i = CURL::Decode(*i);

return StringUtils::Join(segments, "/");
}

std::string URIUtils::ChangeBasePath(const std::string &fromPath, const std::string &fromFile, const std::string &toPath)
{
std::string toFile = fromFile;

// Convert back slashes to forward slashes, if required
if (IsDOSPath(fromPath) && !IsDOSPath(toPath))
StringUtils::Replace(toFile, "\\", "/");

// Handle difference in URL encoded vs. not encoded
if ( ProtocolHasEncodedFilename(CURL(fromPath).GetProtocol() )
&& !ProtocolHasEncodedFilename(CURL(toPath).GetProtocol() ) )
{
toFile = URLDecodePath(toFile); // Decode path
}
else if (!ProtocolHasEncodedFilename(CURL(fromPath).GetProtocol() )
&& ProtocolHasEncodedFilename(CURL(toPath).GetProtocol() ) )
{
toFile = URLEncodePath(toFile); // Encode path
}

// Convert forward slashes to back slashes, if required
if (!IsDOSPath(fromPath) && IsDOSPath(toPath))
StringUtils::Replace(toFile, "/", "\\");

return AddFileToFolder(toPath, toFile);
}

CStdString URIUtils::SubstitutePath(const CStdString& strPath, bool reverse /* = false */)
{
for (CAdvancedSettings::StringMapping::iterator i = g_advancedSettings.m_pathSubstitutions.begin();
i != g_advancedSettings.m_pathSubstitutions.end(); i++)
{
CStdString fromPath;
CStdString toPath;

if (!reverse)
{
if (strncmp(strPath.c_str(), i->first.c_str(), HasSlashAtEnd(i->first.c_str()) ? i->first.size()-1 : i->first.size()) == 0)
{
if (strPath.size() > i->first.size())
return URIUtils::AddFileToFolder(i->second, strPath.substr(i->first.size()));
else
return i->second;
}
fromPath = i->first; // Fake path
toPath = i->second; // Real path
}
else
{
if (strncmp(strPath.c_str(), i->second.c_str(), HasSlashAtEnd(i->second.c_str()) ? i->second.size()-1 : i->second.size()) == 0)
fromPath = i->second; // Real path
toPath = i->first; // Fake path
}

if (strncmp(strPath.c_str(), fromPath.c_str(), HasSlashAtEnd(fromPath) ? fromPath.size() - 1 : fromPath.size()) == 0)
{
if (strPath.size() > fromPath.size())
{
CStdString strSubPathAndFileName = strPath.substr(fromPath.size());
return ChangeBasePath(fromPath, strSubPathAndFileName, toPath); // Fix encoding + slash direction
}
else
{
if (strPath.size() > i->second.size())
return URIUtils::AddFileToFolder(i->first, strPath.substr(i->second.size()));
else
return i->first;
return toPath;
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions xbmc/utils/URIUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ class URIUtils
static void GetCommonPath(CStdString& strPath, const CStdString& strPath2);
static CStdString GetParentPath(const CStdString& strPath);
static bool GetParentPath(const CStdString& strPath, CStdString& strParent);

/* \brief Change the base path of a URL: fromPath/fromFile -> toPath/toFile
Handles changes in path separator and filename URL encoding if necessary to derive toFile.
\param fromPath the base path of the original URL
\param fromFile the filename portion of the original URL
\param toPath the base path of the resulting URL
\return the full path.
*/
static std::string ChangeBasePath(const std::string &fromPath, const std::string &fromFile, const std::string &toPath);

static CStdString SubstitutePath(const CStdString& strPath, bool reverse = false);

static bool IsAddonsPath(const CStdString& strFile);
Expand Down

0 comments on commit 4cad814

Please sign in to comment.