diff --git a/arangod/Auth/User.cpp b/arangod/Auth/User.cpp index 6cf9c14f61..41c47b5722 100644 --- a/arangod/Auth/User.cpp +++ b/arangod/Auth/User.cpp @@ -554,7 +554,7 @@ auth::Level auth::User::collectionAuthLevel(std::string const& dbname, return auth::Level::NONE; // invalid collection names } // we must have got a non-empty collection name when we get here - TRI_ASSERT(!isdigit(cname[0])); + TRI_ASSERT(cname[0] < '0' || cname[0] > '9'); bool isSystem = cname[0] == '_'; if (isSystem) { diff --git a/arangod/Auth/UserManager.cpp b/arangod/Auth/UserManager.cpp index 9c7b37e837..2e9fe1ef2a 100644 --- a/arangod/Auth/UserManager.cpp +++ b/arangod/Auth/UserManager.cpp @@ -777,8 +777,9 @@ auth::Level auth::UserManager::collectionAuthLevel(std::string const& user, return auth::Level::NONE; // no user found } + TRI_ASSERT(!coll.empty()); auth::Level level; - if (isdigit(coll[0])) { + if (coll[0] >= '0' && coll[0] <= '9') { std::string tmpColl = DatabaseFeature::DATABASE->translateCollectionName(dbname, coll); level = it->second.collectionAuthLevel(dbname, tmpColl); } else { diff --git a/arangod/Cluster/ClusterRepairOperations.cpp b/arangod/Cluster/ClusterRepairOperations.cpp index 2107e362ef..04a9ca0270 100644 --- a/arangod/Cluster/ClusterRepairOperations.cpp +++ b/arangod/Cluster/ClusterRepairOperations.cpp @@ -57,7 +57,7 @@ std::vector VersionSort::splitVersion(std::string const& }; for (size_t pos = 0; pos < str.length(); pos++) { - if (isdigit(str[pos])) { + if (str[pos] >= '0' && str[pos] <= '9') { if (from == std::string::npos) { from = pos; } diff --git a/arangod/Replication/SyncerId.cpp b/arangod/Replication/SyncerId.cpp index 041533b127..f6df64d055 100644 --- a/arangod/Replication/SyncerId.cpp +++ b/arangod/Replication/SyncerId.cpp @@ -27,7 +27,6 @@ #include "Rest/GeneralRequest.h" #include -#include using namespace arangodb; @@ -42,7 +41,9 @@ SyncerId SyncerId::fromRequest(GeneralRequest const& request) { if (idStr.empty()) { THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, "syncerId, if set, must not be empty"); } - if (!std::all_of(idStr.begin(), idStr.end(), [](char c) { return std::isdigit(c); })) { + if (!std::all_of(idStr.begin(), idStr.end(), [](char c) { + return c >= '0' && c <= '9'; + })) { THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, "syncerId must be an integer"); } if (idStr[0] == '0') { diff --git a/arangod/Utils/CollectionNameResolver.cpp b/arangod/Utils/CollectionNameResolver.cpp index 04f8949b8a..20d19ecd2e 100644 --- a/arangod/Utils/CollectionNameResolver.cpp +++ b/arangod/Utils/CollectionNameResolver.cpp @@ -74,7 +74,7 @@ TRI_voc_cid_t CollectionNameResolver::getCollectionIdLocal(std::string const& na return 0; } - if (isdigit(name[0])) { + if (name[0] >= '0' && name[0] <= '9') { // name is a numeric id return NumberUtils::atoi_zero(name.data(), name.data() + name.size()); } @@ -107,7 +107,7 @@ TRI_voc_cid_t CollectionNameResolver::getCollectionIdCluster(std::string const& if (name.empty()) { return 0; } - if (isdigit(name[0])) { + if (name[0] >= '0' && name[0] <= '9') { // name is a numeric id TRI_voc_cid_t cid = NumberUtils::atoi_zero(name.data(), name.data() + name.size()); diff --git a/arangod/Utils/UrlHelper.cpp b/arangod/Utils/UrlHelper.cpp index 820a3e0ab6..0b8ddd5541 100644 --- a/arangod/Utils/UrlHelper.cpp +++ b/arangod/Utils/UrlHelper.cpp @@ -22,14 +22,17 @@ #include "UrlHelper.h" -#include -#include #include #include using namespace arangodb; using namespace arangodb::url; +namespace { +// used for URI-encoding +static char const* hexValuesLower = "0123456789abcdef"; +}; + std::ostream& Query::toStream(std::ostream& ostream) const { struct output { std::ostream& ostream; @@ -181,7 +184,10 @@ std::optional const& Location::fragment() const noexcept { // unreserved are A-Z, a-z, 0-9 and - _ . ~ bool arangodb::url::isUnreserved(char c) { - return std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~'; + return (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + c == '-' || c == '_' || c == '.' || c == '~'; } // reserved are: @@ -194,19 +200,22 @@ bool arangodb::url::isReserved(char c) { } std::string arangodb::url::uriEncode(std::string const& raw) { - std::stringstream encoded; - - encoded << std::hex << std::setfill('0'); + std::string encoded; for (auto const c : raw) { if (isUnreserved(c)) { - encoded << c; + // append character as is + encoded.push_back(c); } else { - encoded << '%' << std::setw(2) << static_cast(c); + // must hex-encode the character + encoded.push_back('%'); + auto u = static_cast(c); + encoded.push_back(::hexValuesLower[u >> 4]); + encoded.push_back(::hexValuesLower[u % 16]); } } - return encoded.str(); + return encoded; } std::ostream& arangodb::url::operator<<(std::ostream& ostream, Location const& location) { diff --git a/lib/Basics/FloatingPoint.h b/lib/Basics/FloatingPoint.h index 1409f0e65e..577a21a077 100644 --- a/lib/Basics/FloatingPoint.h +++ b/lib/Basics/FloatingPoint.h @@ -39,7 +39,6 @@ #include "Basics/Common.h" -#include #include #include diff --git a/lib/Basics/StringUtils.cpp b/lib/Basics/StringUtils.cpp index 0c635a9794..2b5950bdd4 100644 --- a/lib/Basics/StringUtils.cpp +++ b/lib/Basics/StringUtils.cpp @@ -24,7 +24,6 @@ #include "StringUtils.h" #include -#include #include #include #include @@ -164,11 +163,17 @@ unsigned char const BASE64U_REVS[256] = { }; inline bool isBase64(unsigned char c) { - return (isalnum(c) || (c == '+') || (c == '/')); + return (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + c == '+' || c == '/'; } inline bool isBase64U(unsigned char c) { - return (isalnum(c) || (c == '-') || (c == '_')); + return (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + c == '-' || c == '_'; } unsigned char consume(char const*& s) { diff --git a/lib/Basics/conversions.cpp b/lib/Basics/conversions.cpp index 9e5b0916a7..78fc875cad 100644 --- a/lib/Basics/conversions.cpp +++ b/lib/Basics/conversions.cpp @@ -62,7 +62,7 @@ double TRI_DoubleString(char const* str) { TRI_set_errno(TRI_ERROR_NO_ERROR); double result = strtod(str, &endptr); - while (isspace(*endptr)) { + while (*endptr == ' ' || *endptr == '\t' || *endptr == '\r' || *endptr == '\n' || *endptr == '\f' || *endptr == '\v') { ++endptr; } @@ -100,7 +100,7 @@ int32_t TRI_Int32String(char const* str) { result = strtol(str, &endptr, 10); #endif - while (isspace(*endptr)) { + while (*endptr == ' ' || *endptr == '\t' || *endptr == '\r' || *endptr == '\n' || *endptr == '\f' || *endptr == '\v') { ++endptr; } @@ -158,7 +158,7 @@ uint32_t TRI_UInt32String(char const* str) { result = (uint32_t)strtoul(str, &endptr, 10); #endif - while (isspace(*endptr)) { + while (*endptr == ' ' || *endptr == '\t' || *endptr == '\r' || *endptr == '\n' || *endptr == '\f' || *endptr == '\v') { ++endptr; } diff --git a/lib/Geo/GeoJson.cpp b/lib/Geo/GeoJson.cpp index b547ef7ab2..f67937e35e 100644 --- a/lib/Geo/GeoJson.cpp +++ b/lib/Geo/GeoJson.cpp @@ -23,7 +23,6 @@ #include "GeoJson.h" -#include #include #include diff --git a/lib/V8/v8-utils.cpp b/lib/V8/v8-utils.cpp index 8c8ad3010e..bab7a8bce5 100644 --- a/lib/V8/v8-utils.cpp +++ b/lib/V8/v8-utils.cpp @@ -35,7 +35,6 @@ #include "Basics/win-utils.h" #endif -#include #include #include #include @@ -1335,7 +1334,7 @@ static void JS_ChMod(v8::FunctionCallbackInfo const& args) { long mode = 0; for (uint32_t i = 0; i < length; ++i) { - if (!isdigit(modeStr[i])) { + if (modeStr[i] < '0' || modeStr[i] > '9') { TRI_V8_THROW_TYPE_ERROR( " must be a string with up to 4 octal digits in it plus a " "leading zero.");