Check for Invalid Characters in Output Filename (#274)

Fixes #268.
This commit is contained in:
Dan 2020-06-26 22:33:50 +01:00 committed by GitHub
parent 0fa0738db8
commit d2c38c542f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 15 deletions

View File

@ -33,14 +33,9 @@ char getDirSeparator()
string extractFileDir(const string& fileName)
{
size_t index = fileName.find_last_of('/');
size_t index = fileName.find_last_of(getDirSeparator());
if (index != string::npos)
return fileName.substr(0, index + 1);
#ifdef _WIN32
index = fileName.find_last_of('\\');
if (index != string::npos)
return fileName.substr(0, index + 1);
#endif
return "";
}

View File

@ -5,6 +5,7 @@
#include <cstring>
#include <iomanip>
#include <ostream>
#include <regex>
#include <sstream>
#ifndef _WIN32
@ -19,6 +20,25 @@
#include "fs/directory.h"
namespace
{
const std::regex& invalidChars()
{
static const std::regex invalid(
#ifndef _WIN32
// / and ASCII 0 to 31
"[/\\x00-\\x1F]"
#else
// <>:"/|?\*, ASCII 0 to 31 and all reserved names such as CON or LPT1
// see here: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
"[:<>\"/|?\\*\\x00-\\x1F]|^CON$|^PRN$|^AUX$|^NUL$|^COM\d$|^LPT\d$"
#endif
,
std::regex_constants::ECMAScript | std::regex_constants::optimize);
return invalid;
}
} // namespace
using namespace std;
uint64_t my_ntohll(const uint64_t& original)
@ -303,7 +323,7 @@ string extractFileName(const string& src)
if (endPos == src.size())
endPos = i;
}
else if (src[i] == '/' || src[i] == '\\')
else if (src[i] == getDirSeparator())
{
string rez = src.substr(i + 1, endPos - i - 1);
if (rez.size() > 0 && rez[rez.size() - 1] == '\"')
@ -319,10 +339,7 @@ string extractFileName2(const string& src, bool withExt)
string fileName = src;
size_t extSep = fileName.find_last_of('.');
size_t dirSep = fileName.find_last_of('/');
if (dirSep == string::npos)
dirSep = fileName.find_last_of('\\');
size_t dirSep = fileName.find_last_of(getDirSeparator());
if (extSep != string::npos && !withExt)
fileName = fileName.substr(0, extSep);
@ -336,7 +353,7 @@ string extractFileName2(const string& src, bool withExt)
string extractFilePath(const string& src)
{
for (int i = src.size() - 1; i >= 0; i--)
if (src[i] == '/' || src[i] == '\\')
if (src[i] == getDirSeparator())
{
string rez = src.substr(0, i);
return rez;
@ -350,11 +367,21 @@ string closeDirPath(const string& src, char delimiter)
delimiter = getDirSeparator();
if (src.length() == 0)
return src;
if (src[src.length() - 1] == '/' || src[src.length() - 1] == '\\')
if (src[src.length() - 1] == getDirSeparator())
return src;
return src + delimiter;
}
// extract the filename from a path, check for invalid characters
bool isValidFileName(const string& src)
{
string filename = extractFileName(src);
// invalidChars() returns a different regex pattern for Windows or Unix
bool isvalid = !(std::regex_search(filename, invalidChars()));
return isvalid;
}
string trimStr(const string& value)
{
const char* bufStart = value.c_str();

View File

@ -2,6 +2,7 @@
#define __T_TYPES_H
#include <cstdint>
#include <regex>
#include <string>
#include <vector>
@ -45,6 +46,7 @@ std::string extractFileName(const std::string& src);
std::string extractFileName2(const std::string& src, bool withExt = true);
std::string extractFilePath(const std::string& src);
std::string closeDirPath(const std::string& src, char delimiter = ' ');
bool isValidFileName(const std::string& src);
std::vector<std::string> splitQuotedStr(const char* str, char splitter);

View File

@ -735,8 +735,13 @@ int main(int argc, char** argv)
LTRACE(LT_INFO, 2, "HEVC stream detected: changing Blu-Ray version to V3.");
V3_flags |= HDMV_V3;
}
// output path - is checked for invalid characters on our platform
string dstFile = unquoteStr(argv[2]);
if (!isValidFileName(dstFile))
throw runtime_error(string("Output filename is invalid: ") + dstFile);
if (dt != DT_NONE)
{
if (!blurayHelper.open(dstFile, dt, muxerManager.totalSize(), muxerManager.getExtraISOBlocks()))
@ -803,8 +808,15 @@ int main(int argc, char** argv)
sMuxer.openMetaFile(argv[1]);
if (sMuxer.getTrackCnt() == 0)
THROW(ERR_COMMON, "No tracks selected");
createDir(unquoteStr(argv[2]), true);
sMuxer.doMux(unquoteStr(argv[2]), 0);
// output path - is checked for invalid characters on our platform
string dstFile = unquoteStr(argv[2]);
if (!isValidFileName(dstFile))
throw runtime_error(string("Output filename is invalid: ") + dstFile);
createDir(dstFile, true);
sMuxer.doMux(dstFile, 0);
LTRACE(LT_INFO, 2, "Demux complete.");
}
auto endTime = std::chrono::steady_clock::now();