More code cleanups

pull/128/merge
Nils Maier 2013-08-25 17:02:24 +02:00
parent 9e7579b475
commit 8e6e46dfcf
2 changed files with 241 additions and 206 deletions

View File

@ -105,19 +105,24 @@ bool parse(UriStruct& result, const std::string& uri)
int rv; int rv;
const char* p = uri.c_str(); const char* p = uri.c_str();
rv = uri_split(&res, p); rv = uri_split(&res, p);
if(rv == 0) { if(rv != 0) {
return false;
}
result.protocol.assign(p + res.fields[USR_SCHEME].off, result.protocol.assign(p + res.fields[USR_SCHEME].off,
res.fields[USR_SCHEME].len); res.fields[USR_SCHEME].len);
result.host.assign(p + res.fields[USR_HOST].off, res.fields[USR_HOST].len); result.host.assign(p + res.fields[USR_HOST].off, res.fields[USR_HOST].len);
if(res.port == 0) { if (res.port == 0) {
uint16_t defPort; uint16_t defPort;
if((defPort = getDefaultPort(result.protocol)) == 0) { if((defPort = getDefaultPort(result.protocol)) == 0) {
return false; return false;
} }
result.port = defPort; result.port = defPort;
} else { }
else {
result.port = res.port; result.port = res.port;
} }
if(res.field_set & (1 << USR_PATH)) { if(res.field_set & (1 << USR_PATH)) {
if(res.field_set & (1 << USR_BASENAME)) { if(res.field_set & (1 << USR_BASENAME)) {
result.dir.assign(p + res.fields[USR_PATH].off, result.dir.assign(p + res.fields[USR_PATH].off,
@ -125,45 +130,51 @@ bool parse(UriStruct& result, const std::string& uri)
res.fields[USR_BASENAME].len); res.fields[USR_BASENAME].len);
result.file.assign(p + res.fields[USR_BASENAME].off, result.file.assign(p + res.fields[USR_BASENAME].off,
res.fields[USR_BASENAME].len); res.fields[USR_BASENAME].len);
} else { }
else {
result.dir.assign(p + res.fields[USR_PATH].off, result.dir.assign(p + res.fields[USR_PATH].off,
res.fields[USR_PATH].len); res.fields[USR_PATH].len);
result.file = A2STR::NIL; result.file = A2STR::NIL;
} }
} else { }
else {
result.dir = "/"; result.dir = "/";
result.file = A2STR::NIL; result.file = A2STR::NIL;
} }
if(res.field_set & (1 << USR_QUERY)) { if(res.field_set & (1 << USR_QUERY)) {
result.query = "?"; result.query = "?";
result.query.append(p + res.fields[USR_QUERY].off, result.query.append(p + res.fields[USR_QUERY].off,
res.fields[USR_QUERY].len); res.fields[USR_QUERY].len);
} else { }
else {
result.query = A2STR::NIL; result.query = A2STR::NIL;
} }
if(res.field_set & (1 << USR_USER)) { if(res.field_set & (1 << USR_USER)) {
result.username.assign(p + res.fields[USR_USER].off, result.username.assign(p + res.fields[USR_USER].off,
res.fields[USR_USER].len); res.fields[USR_USER].len);
result.username = util::percentDecode(result.username.begin(), result.username = util::percentDecode(result.username.begin(),
result.username.end()); result.username.end());
} else { }
else {
result.username = A2STR::NIL; result.username = A2STR::NIL;
} }
if(res.field_set & (1 << USR_PASSWD)) { if(res.field_set & (1 << USR_PASSWD)) {
result.hasPassword = true; result.hasPassword = true;
result.password.assign(p + res.fields[USR_PASSWD].off, result.password.assign(p + res.fields[USR_PASSWD].off,
res.fields[USR_PASSWD].len); res.fields[USR_PASSWD].len);
result.password = util::percentDecode(result.password.begin(), result.password = util::percentDecode(result.password.begin(),
result.password.end()); result.password.end());
} else { }
else {
result.hasPassword = false; result.hasPassword = false;
result.password = A2STR::NIL; result.password = A2STR::NIL;
} }
result.ipv6LiteralAddress = res.flags & USF_IPV6ADDR; result.ipv6LiteralAddress = res.flags & USF_IPV6ADDR;
return true; return true;
} else {
return false;
}
} }
std::string getFieldString(const uri_split_result& res, int field, std::string getFieldString(const uri_split_result& res, int field,
@ -171,9 +182,8 @@ std::string getFieldString(const uri_split_result& res, int field,
{ {
if(res.field_set & (1 << field)) { if(res.field_set & (1 << field)) {
return std::string(base + res.fields[field].off, res.fields[field].len); return std::string(base + res.fields[field].off, res.fields[field].len);
} else {
return "";
} }
return "";
} }
std::string construct(const UriStruct& us) std::string construct(const UriStruct& us)
@ -193,39 +203,48 @@ std::string construct(const UriStruct& us)
res += "["; res += "[";
res += us.host; res += us.host;
res += "]"; res += "]";
} else { }
else {
res += us.host; res += us.host;
} }
uint16_t defPort= getDefaultPort(us.protocol);
uint16_t defPort = getDefaultPort(us.protocol);
if(us.port != 0 && defPort != us.port) { if(us.port != 0 && defPort != us.port) {
res += fmt(":%u", us.port); res += fmt(":%u", us.port);
} }
res += us.dir; res += us.dir;
if(us.dir.empty() || us.dir[us.dir.size()-1] != '/') { if(us.dir.empty() || us.dir[us.dir.size()-1] != '/') {
res += "/"; res += "/";
} }
res += us.file; res += us.file;
res += us.query; res += us.query;
return res; return res;
} }
enum { namespace {
enum {
NPATH_START, NPATH_START,
NPATH_SLASH, NPATH_SLASH,
NPATH_SDOT, NPATH_SDOT,
NPATH_DDOT, NPATH_DDOT,
NPATH_PATHCOMP NPATH_PATHCOMP
}; };
}
std::string normalizePath(std::string path) std::string normalizePath(std::string path)
{ {
std::string::iterator begin = path.begin(), out = begin; typedef std::string::iterator itr;
itr begin = path.begin(), out = begin;
int state = NPATH_START; int state = NPATH_START;
bool startWithSlash = false; bool startWithSlash = false;
std::vector<int> range; std::vector<int> range;
// 32 is arbitrary // 32 is arbitrary
range.reserve(32); range.reserve(32);
for(std::string::iterator in = begin, eoi = path.end(); in != eoi; ++in) {
for(itr in = begin, eoi = path.end(); in != eoi; ++in) {
switch(state) { switch(state) {
case NPATH_START: case NPATH_START:
switch(*in) { switch(*in) {
@ -295,6 +314,7 @@ std::string normalizePath(std::string path)
break; break;
} }
} }
switch(state) { switch(state) {
case NPATH_SDOT: case NPATH_SDOT:
range.pop_back(); range.pop_back();
@ -310,18 +330,21 @@ std::string normalizePath(std::string path)
default: default:
break; break;
} }
if(startWithSlash) { if(startWithSlash) {
++out; ++out;
} }
for(int i = 0; i < (int)range.size(); i += 2) { for(int i = 0; i < (int)range.size(); i += 2) {
std::string::iterator a = begin+range[i]; itr a = begin + range[i];
std::string::iterator b = begin+range[i+1]; itr b = begin + range[i+1];
if(a == out) { if(a == out) {
out = b; out = b;
} else { } else {
out = std::copy(a, b, out); out = std::copy(a, b, out);
} }
} }
path.erase(out, path.end()); path.erase(out, path.end());
return path; return path;
} }
@ -333,16 +356,20 @@ std::string joinPath(std::string basePath,
{ {
if(newPathFirst == newPathLast) { if(newPathFirst == newPathLast) {
return basePath; return basePath;
} else if(basePath.empty() || *newPathFirst == '/') { }
if(basePath.empty() || *newPathFirst == '/') {
return normalizePath(std::string(newPathFirst, newPathLast)); return normalizePath(std::string(newPathFirst, newPathLast));
} else if(basePath[basePath.size()-1] == '/') { }
basePath.append(newPathFirst, newPathLast);
return normalizePath(basePath); if(basePath[basePath.size()-1] == '/') {
} else {
basePath += "/";
basePath.append(newPathFirst, newPathLast); basePath.append(newPathFirst, newPathLast);
return normalizePath(basePath); return normalizePath(basePath);
} }
basePath += "/";
basePath.append(newPathFirst, newPathLast);
return normalizePath(basePath);
} }
} // namespace } // namespace
@ -356,11 +383,13 @@ std::string joinUri(const std::string& baseUri, const std::string& uri)
UriStruct us; UriStruct us;
if(parse(us, uri)) { if(parse(us, uri)) {
return uri; return uri;
} else { }
UriStruct bus; UriStruct bus;
if(!parse(bus, baseUri)) { if(!parse(bus, baseUri)) {
return uri; return uri;
} }
std::string::const_iterator qend; std::string::const_iterator qend;
for(qend = uri.begin(); qend != uri.end(); ++qend) { for(qend = uri.begin(); qend != uri.end(); ++qend) {
if(*qend == '#') { if(*qend == '#') {
@ -385,7 +414,6 @@ std::string joinUri(const std::string& baseUri, const std::string& uri)
} }
res.append(end, qend); res.append(end, qend);
return res; return res;
}
} }
} // namespace uri } // namespace uri

View File

@ -279,8 +279,8 @@ bool isHexDigit(const char c)
bool isHexDigit(const std::string& s) bool isHexDigit(const std::string& s)
{ {
for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) { for (const auto& c : s) {
if(!isHexDigit(*i)) { if(!isHexDigit(c)) {
return false; return false;
} }
} }
@ -676,15 +676,15 @@ void computeHeadPieces
if(head == 0) { if(head == 0) {
return; return;
} }
for(auto fi = fileEntries.begin(), eoi = fileEntries.end(); fi != eoi; ++fi) { for (const auto& fi: fileEntries) {
if((*fi)->getLength() == 0) { if(fi->getLength() == 0) {
continue; continue;
} }
size_t lastIndex = const size_t lastIndex = (fi->getOffset() +
((*fi)->getOffset()+std::min(head, (*fi)->getLength())-1)/pieceLength; std::min(head, fi->getLength()) - 1
for(size_t index = (*fi)->getOffset()/pieceLength; ) / pieceLength;
index <= lastIndex; ++index) { for(size_t idx = fi->getOffset() / pieceLength; idx <= lastIndex; ++idx) {
indexes.push_back(index); indexes.push_back(idx);
} }
} }
} }
@ -700,16 +700,16 @@ void computeTailPieces
if(tail == 0) { if(tail == 0) {
return; return;
} }
for(auto fi = fileEntries.begin(), eoi = fileEntries.end(); fi != eoi; ++fi) { for (const auto& fi: fileEntries) {
if((*fi)->getLength() == 0) { if(fi->getLength() == 0) {
continue; continue;
} }
int64_t endOffset = (*fi)->getLastOffset(); int64_t endOffset = fi->getLastOffset();
size_t fromIndex = size_t fromIndex = (endOffset - 1 - (std::min(tail, fi->getLength()) - 1)) /
(endOffset-1-(std::min(tail, (*fi)->getLength())-1))/pieceLength; pieceLength;
for(size_t index = fromIndex; index <= (endOffset-1)/pieceLength; const size_t toIndex = (endOffset - 1) / pieceLength;
++index) { while (fromIndex <= toIndex) {
indexes.push_back(index); indexes.push_back(fromIndex++);
} }
} }
} }
@ -724,23 +724,26 @@ void parsePrioritizePieceRange
std::vector<size_t> indexes; std::vector<size_t> indexes;
std::vector<Scip> parts; std::vector<Scip> parts;
splitIter(src.begin(), src.end(), std::back_inserter(parts), ',', true); splitIter(src.begin(), src.end(), std::back_inserter(parts), ',', true);
for(std::vector<Scip>::const_iterator i = parts.begin(), for (const auto& i: parts) {
eoi = parts.end(); i != eoi; ++i) { if(util::streq(i.first, i.second, "head")) {
if(util::streq((*i).first, (*i).second, "head")) {
computeHeadPieces(indexes, fileEntries, pieceLength, defaultSize); computeHeadPieces(indexes, fileEntries, pieceLength, defaultSize);
} else if(util::startsWith((*i).first, (*i).second, "head=")) { }
std::string sizestr((*i).first+5, (*i).second); else if(util::startsWith(i.first, i.second, "head=")) {
std::string sizestr(i.first + 5, i.second);
computeHeadPieces(indexes, fileEntries, pieceLength, computeHeadPieces(indexes, fileEntries, pieceLength,
std::max((int64_t)0, getRealSize(sizestr))); std::max((int64_t)0, getRealSize(sizestr)));
} else if(util::streq((*i).first, (*i).second, "tail")) { }
else if(util::streq(i.first, i.second, "tail")) {
computeTailPieces(indexes, fileEntries, pieceLength, defaultSize); computeTailPieces(indexes, fileEntries, pieceLength, defaultSize);
} else if(util::startsWith((*i).first, (*i).second, "tail=")) { }
std::string sizestr((*i).first+5, (*i).second); else if(util::startsWith(i.first, i.second, "tail=")) {
std::string sizestr(i.first + 5, i.second);
computeTailPieces(indexes, fileEntries, pieceLength, computeTailPieces(indexes, fileEntries, pieceLength,
std::max((int64_t)0, getRealSize(sizestr))); std::max((int64_t)0, getRealSize(sizestr)));
} else { }
else {
throw DL_ABORT_EX(fmt("Unrecognized token %s", throw DL_ABORT_EX(fmt("Unrecognized token %s",
std::string((*i).first, (*i).second).c_str())); std::string(i.first, i.second).c_str()));
} }
} }
std::sort(indexes.begin(), indexes.end()); std::sort(indexes.begin(), indexes.end());
@ -1177,7 +1180,8 @@ std::string getContentDispositionFilename(const std::string& header)
header.c_str(), header.size()); header.c_str(), header.size());
if(rv == -1) { if(rv == -1) {
return ""; return "";
} else { }
std::string res; std::string res;
if(!charset || strieq(charset, charset+charsetlen, "iso-8859-1")) { if(!charset || strieq(charset, charset+charsetlen, "iso-8859-1")) {
res = iso8859p1ToUtf8(cdval, rv); res = iso8859p1ToUtf8(cdval, rv);
@ -1187,10 +1191,8 @@ std::string getContentDispositionFilename(const std::string& header)
if(!detectDirTraversal(res) && if(!detectDirTraversal(res) &&
res.find_first_of("/\\") == std::string::npos) { res.find_first_of("/\\") == std::string::npos) {
return res; return res;
} else { }
return ""; return "";
}
}
} }
std::string toUpper(std::string src) std::string toUpper(std::string src)
@ -1335,24 +1337,23 @@ void setGlobalSignalHandler(int sig, sigset_t* mask, signal_handler_t handler,
std::string getHomeDir() std::string getHomeDir()
{ {
const char* p = getenv("HOME"); const char* p = getenv("HOME");
if(p) { if (p) {
return p; return p;
} else { }
#ifdef __MINGW32__ #ifdef __MINGW32__
p = getenv("USERPROFILE"); p = getenv("USERPROFILE");
if(p) { if (p) {
return p; return p;
} else { }
p = getenv("HOMEDRIVE"); p = getenv("HOMEDRIVE");
if(p) { if (p) {
std::string homeDir = p; std::string homeDir = p;
p = getenv("HOMEPATH"); p = getenv("HOMEPATH");
if(p) { if (p) {
homeDir += p; homeDir += p;
return homeDir; return homeDir;
} }
} }
}
#elif HAVE_PWD_H #elif HAVE_PWD_H
passwd* pw = getpwuid(geteuid()); passwd* pw = getpwuid(geteuid());
if(pw && pw->pw_dir) { if(pw && pw->pw_dir) {
@ -1360,7 +1361,6 @@ std::string getHomeDir()
} }
#endif // HAVE_PWD_H #endif // HAVE_PWD_H
return A2STR::NIL; return A2STR::NIL;
}
} }
int64_t getRealSize(const std::string& sizeWithUnit) int64_t getRealSize(const std::string& sizeWithUnit)
@ -1387,7 +1387,8 @@ int64_t getRealSize(const std::string& sizeWithUnit)
if(!parseLLIntNoThrow(v, size) || v < 0) { if(!parseLLIntNoThrow(v, size) || v < 0) {
throw DL_ABORT_EX(fmt("Bad or negative value detected: %s", throw DL_ABORT_EX(fmt("Bad or negative value detected: %s",
sizeWithUnit.c_str())); sizeWithUnit.c_str()));
} else if(INT64_MAX/mult < v) { }
if(INT64_MAX/mult < v) {
throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE, throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"overflow/underflow")); "overflow/underflow"));
} }
@ -1474,9 +1475,7 @@ void mkdirs(const std::string& dirpath)
if(!dir.mkdirs()) { if(!dir.mkdirs()) {
int errNum = errno; int errNum = errno;
if(!dir.isDir()) { if(!dir.isDir()) {
throw DL_ABORT_EX3 throw DL_ABORT_EX3(errNum, fmt(EX_MAKE_DIR, dir.getPath().c_str(),
(errNum,
fmt(EX_MAKE_DIR, dir.getPath().c_str(),
safeStrerror(errNum).c_str()), safeStrerror(errNum).c_str()),
error_code::DIR_CREATE_ERROR); error_code::DIR_CREATE_ERROR);
} }
@ -1518,8 +1517,7 @@ void* allocateAlignedMemory(size_t alignment, size_t size)
void* buffer; void* buffer;
int res; int res;
if((res = posix_memalign(&buffer, alignment, size)) != 0) { if((res = posix_memalign(&buffer, alignment, size)) != 0) {
throw FATAL_EXCEPTION throw FATAL_EXCEPTION(fmt("Error in posix_memalign: %s",
(fmt("Error in posix_memalign: %s",
util::safeStrerror(res).c_str())); util::safeStrerror(res).c_str()));
} }
return buffer; return buffer;
@ -1663,11 +1661,13 @@ std::string applyDir(const std::string& dir, const std::string& relPath)
if(dir.empty()) { if(dir.empty()) {
s = "./"; s = "./";
s += relPath; s += relPath;
} else { }
else {
s = dir; s = dir;
if(dir == "/") { if(dir == "/") {
s += relPath; s += relPath;
} else { }
else {
s += "/"; s += "/";
s += relPath; s += relPath;
} }
@ -1728,18 +1728,19 @@ bool detectDirTraversal(const std::string& s)
if(s.empty()) { if(s.empty()) {
return false; return false;
} }
for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) { for (const auto& ch: s) {
unsigned char c = *i; if (in(ch, 0x00u, 0x1fu) || ch == 0x7fu) {
if(in(c, 0x00u, 0x1fu) || c == 0x7fu) {
return true; return true;
} }
} }
return s == "." || s == ".." || s[0] == '/' || return s == "." || s == ".." || s[0] == '/' ||
util::startsWith(s, "./") || util::startsWith(s, "../") || util::startsWith(s, "./") ||
util::startsWith(s, "../") ||
s.find("/../") != std::string::npos || s.find("/../") != std::string::npos ||
s.find("/./") != std::string::npos || s.find("/./") != std::string::npos ||
s[s.size()-1] == '/' || s[s.size()-1] == '/' ||
util::endsWith(s, "/.") || util::endsWith(s, "/.."); util::endsWith(s, "/.") ||
util::endsWith(s, "/..");
} }
std::string escapePath(const std::string& s) std::string escapePath(const std::string& s)
@ -1810,9 +1811,8 @@ void executeHook
numFilesStr.c_str(), numFilesStr.c_str(),
firstFilename.c_str())); firstFilename.c_str()));
pid_t cpid = fork(); pid_t cpid = fork();
if(cpid == -1) { if (cpid > 0) {
A2_LOG_ERROR("fork() failed. Cannot execute user command."); // child!
} else if(cpid == 0) {
execlp(command.c_str(), execlp(command.c_str(),
command.c_str(), command.c_str(),
gidStr.c_str(), gidStr.c_str(),
@ -1821,8 +1821,15 @@ void executeHook
reinterpret_cast<char*>(0)); reinterpret_cast<char*>(0));
perror(("Could not execute user command: "+command).c_str()); perror(("Could not execute user command: "+command).c_str());
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
return;
} }
#else
if(cpid == -1) {
A2_LOG_ERROR("fork() failed. Cannot execute user command.");
}
return;
#else // __MINGW32__
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
STARTUPINFOW si; STARTUPINFOW si;
@ -1832,6 +1839,8 @@ void executeHook
bool batch = util::iendsWith(command, ".bat"); bool batch = util::iendsWith(command, ".bat");
std::string cmdline; std::string cmdline;
std::string cmdexe; std::string cmdexe;
// XXX batch handling, in particular quoting, correct?
if(batch) { if(batch) {
const char* p = getenv("windir"); const char* p = getenv("windir");
if(p) { if(p) {
@ -1878,6 +1887,8 @@ void executeHook
if(!rc) { if(!rc) {
A2_LOG_ERROR("CreateProcess() failed. Cannot execute user command."); A2_LOG_ERROR("CreateProcess() failed. Cannot execute user command.");
} }
return;
#endif #endif
} }
@ -1912,11 +1923,10 @@ void executeHookByOptName
std::string createSafePath std::string createSafePath
(const std::string& dir, const std::string& filename) (const std::string& dir, const std::string& filename)
{ {
return util::applyDir return util::applyDir(dir, util::isUtf8(filename) ?
(dir, util::fixTaintedBasename(filename) :
util::isUtf8(filename)? util::escapePath(util::percentEncode(filename))
util::fixTaintedBasename(filename): );
util::escapePath(util::percentEncode(filename)));
} }
std::string encodeNonUtf8(const std::string& s) std::string encodeNonUtf8(const std::string& s)
@ -1926,11 +1936,10 @@ std::string encodeNonUtf8(const std::string& s)
std::string makeString(const char* str) std::string makeString(const char* str)
{ {
if(str) { if(!str) {
return str;
} else {
return A2STR::NIL; return A2STR::NIL;
} }
return str;
} }
std::string safeStrerror(int errNum) std::string safeStrerror(int errNum)
@ -1944,9 +1953,8 @@ bool noProxyDomainMatch
{ {
if(!domain.empty() && domain[0] == '.' && !util::isNumericHost(hostname)) { if(!domain.empty() && domain[0] == '.' && !util::isNumericHost(hostname)) {
return util::endsWith(hostname, domain); return util::endsWith(hostname, domain);
} else {
return hostname == domain;
} }
return hostname == domain;
} }
bool tlsHostnameMatch(const std::string& pattern, const std::string& hostname) bool tlsHostnameMatch(const std::string& pattern, const std::string& hostname)
@ -1987,11 +1995,10 @@ bool tlsHostnameMatch(const std::string& pattern, const std::string& hostname)
if(hnLeftLabelEnd - hostname.begin() < ptLeftLabelEnd - pattern.begin()) { if(hnLeftLabelEnd - hostname.begin() < ptLeftLabelEnd - pattern.begin()) {
return false; return false;
} }
return return istartsWith(hostname.begin(), hnLeftLabelEnd, pattern.begin(),
istartsWith(hostname.begin(), hnLeftLabelEnd, ptWildcard) &&
pattern.begin(), ptWildcard) && iendsWith(hostname.begin(), hnLeftLabelEnd, ptWildcard + 1,
iendsWith(hostname.begin(), hnLeftLabelEnd, ptLeftLabelEnd);
ptWildcard+1, ptLeftLabelEnd);
} }
bool strieq(const std::string& a, const char* b) bool strieq(const std::string& a, const char* b)