1
0
Fork 0

retire some old string functions, and make encode/decodeHex copy less data around (#5313)

This commit is contained in:
Jan 2018-05-14 10:06:45 +02:00 committed by GitHub
parent e843e3e6c5
commit fe586dac40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 193 additions and 384 deletions

View File

@ -26,6 +26,7 @@
#include "Basics/ReadLocker.h" #include "Basics/ReadLocker.h"
#include "Basics/StaticStrings.h" #include "Basics/StaticStrings.h"
#include "Basics/StringRef.h" #include "Basics/StringRef.h"
#include "Basics/StringUtils.h"
#include "Basics/VelocyPackHelper.h" #include "Basics/VelocyPackHelper.h"
#include "Basics/WriteLocker.h" #include "Basics/WriteLocker.h"
#include "Basics/tri-strings.h" #include "Basics/tri-strings.h"
@ -52,7 +53,6 @@ static int HexHashFromData(std::string const& hashMethod,
std::string const& str, std::string& outHash) { std::string const& str, std::string& outHash) {
char* crypted = nullptr; char* crypted = nullptr;
size_t cryptedLength; size_t cryptedLength;
char* hex;
try { try {
if (hashMethod == "sha1") { if (hashMethod == "sha1") {
@ -80,26 +80,19 @@ static int HexHashFromData(std::string const& hashMethod,
return TRI_ERROR_BAD_PARAMETER; return TRI_ERROR_BAD_PARAMETER;
} }
} catch (...) { } catch (...) {
// SslInterface::ssl....() allocate strings with new, which might throw // SslInterface::ssl....() allocates strings with new, which might throw
// exceptions // exceptions
return TRI_ERROR_FAILED; return TRI_ERROR_FAILED;
} }
TRI_DEFER(delete[] crypted);
if (crypted == nullptr || cryptedLength == 0) { if (crypted == nullptr || cryptedLength == 0) {
delete[] crypted;
return TRI_ERROR_OUT_OF_MEMORY; return TRI_ERROR_OUT_OF_MEMORY;
} }
size_t hexLen; outHash = basics::StringUtils::encodeHex(crypted, cryptedLength);
hex = TRI_EncodeHexString(crypted, cryptedLength, &hexLen);
delete[] crypted;
if (hex == nullptr) {
return TRI_ERROR_OUT_OF_MEMORY;
}
TRI_DEFER(TRI_FreeString(hex));
outHash = std::string(hex, hexLen);
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }

View File

@ -33,8 +33,8 @@
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "zlib.h" #include "zlib.h"
#include "zconf.h" #include "zconf.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// helper functions // helper functions
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -2265,26 +2265,75 @@ size_t numEntries(std::string const& sourceStr, std::string const& delimiter) {
return k; return k;
} }
std::string encodeHex(std::string const& str) { std::string encodeHex(char const* value, size_t length) {
size_t len; static char const* hexValues = "0123456789abcdef";
char* tmp = TRI_EncodeHexString(str.c_str(), str.length(), &len);
std::string result;
result.reserve(length * 2);
if (tmp != nullptr) { char const* p = value;
TRI_DEFER(TRI_FreeString(tmp)); char const* e = p + length;
return std::string(tmp, len); while (p < e) {
auto c = static_cast<unsigned char>(*p++);
result.push_back(hexValues[c >> 4]);
result.push_back(hexValues[c % 16]);
} }
return std::string();
return result;
} }
std::string decodeHex(std::string const& str) { std::string encodeHex(std::string const& value) {
size_t len; return encodeHex(value.data(), value.size());
char* tmp = TRI_DecodeHexString(str.c_str(), str.length(), &len); }
if (tmp != nullptr) { std::string decodeHex(char const* value, size_t length) {
TRI_DEFER(TRI_FreeString(tmp)); std::string result;
return std::string(tmp, len); // input string length should be divisable by 2
// but we do not assert for this here, because it might
// be an end user error
if ((length & 1) != 0 || length == 0) {
// invalid or empty
return std::string();
} }
return std::string();
result.reserve(length / 2);
unsigned char const* p = reinterpret_cast<unsigned char const*>(value);
unsigned char const* e = p + length;
while (p + 2 <= e) {
unsigned char c = *p++;
unsigned char v = 0;
if (c >= '0' && c <= '9') {
v = (c - '0') << 4;
} else if (c >= 'a' && c <= 'f') {
v = (c - 'a' + 10) << 4;
} else if (c >= 'A' && c <= 'F') {
v = (c - 'A' + 10) << 4;
} else {
// invalid input character
return std::string();
}
c = *p++;
if (c >= '0' && c <= '9') {
v += (c - '0');
} else if (c >= 'a' && c <= 'f') {
v += (c - 'a' + 10);
} else if (c >= 'A' && c <= 'F') {
v += (c - 'A' + 10);
} else {
// invalid input character
return std::string();
}
result.push_back(v);
}
return result;
}
std::string decodeHex(std::string const& value) {
return decodeHex(value.data(), value.size());
} }
bool gzipUncompress(char const* compressed, size_t compressedLength, std::string& uncompressed) { bool gzipUncompress(char const* compressed, size_t compressedLength, std::string& uncompressed) {

View File

@ -30,143 +30,89 @@
namespace arangodb { namespace arangodb {
namespace basics { namespace basics {
////////////////////////////////////////////////////////////////////////////////
/// @brief collection of string utility functions /// @brief collection of string utility functions
/// ///
/// This namespace holds function used for string manipulation. /// This namespace holds function used for string manipulation.
////////////////////////////////////////////////////////////////////////////////
namespace StringUtils { namespace StringUtils {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// STRING AND STRING POINTER // STRING AND STRING POINTER
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a C string using new /// @brief creates a C string using new
////////////////////////////////////////////////////////////////////////////////
char* duplicate(std::string const&); char* duplicate(std::string const&);
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a C string using new /// @brief creates a C string using new
////////////////////////////////////////////////////////////////////////////////
char* duplicate(char const*, size_t); char* duplicate(char const*, size_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a C string using new /// @brief creates a C string using new
////////////////////////////////////////////////////////////////////////////////
char* duplicate(char const*); char* duplicate(char const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief deletes and clears a string /// @brief deletes and clears a string
/// ///
/// The string is cleared using memset and then deleted. The pointer is /// The string is cleared using memset and then deleted. The pointer is
/// set to 0. /// set to 0.
////////////////////////////////////////////////////////////////////////////////
void destroy(char*&); void destroy(char*&);
////////////////////////////////////////////////////////////////////////////////
/// @brief deletes and clears a string /// @brief deletes and clears a string
/// ///
/// The string is cleared using memset and then deleted. The pointer is /// The string is cleared using memset and then deleted. The pointer is
/// set to 0. /// set to 0.
////////////////////////////////////////////////////////////////////////////////
void destroy(char*&, size_t); void destroy(char*&, size_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief deletes but does not clear a character string /// @brief deletes but does not clear a character string
/// ///
/// The pointer deleted and then set to 0. /// The pointer deleted and then set to 0.
////////////////////////////////////////////////////////////////////////////////
void erase(char*&); void erase(char*&);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// STRING CONVERSION // STRING CONVERSION
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief capitalize string /// @brief capitalize string
/// ///
/// This method converts characters at the beginning of a word to uppercase /// This method converts characters at the beginning of a word to uppercase
/// and remove any whitespaces. If first is true the first character of the /// and remove any whitespaces. If first is true the first character of the
/// first word is also converted to uppercase. Name must not be empty. /// first word is also converted to uppercase. Name must not be empty.
////////////////////////////////////////////////////////////////////////////////
std::string capitalize(std::string const& name, bool first = true); std::string capitalize(std::string const& name, bool first = true);
////////////////////////////////////////////////////////////////////////////////
/// @brief separate words /// @brief separate words
/// ///
/// This method converts all characters to lowercase and separates /// This method converts all characters to lowercase and separates
/// the words with a given character. Name must not be empty. /// the words with a given character. Name must not be empty.
////////////////////////////////////////////////////////////////////////////////
std::string separate(std::string const& name, char separator = '-'); std::string separate(std::string const& name, char separator = '-');
////////////////////////////////////////////////////////////////////////////////
/// @brief escape unicode /// @brief escape unicode
/// ///
/// This method escapes a unicode character string by replacing the unicode /// This method escapes a unicode character string by replacing the unicode
/// characters by a \\uXXXX sequence. /// characters by a \\uXXXX sequence.
////////////////////////////////////////////////////////////////////////////////
std::string escapeUnicode(std::string const& name, bool escapeSlash = true); std::string escapeUnicode(std::string const& name, bool escapeSlash = true);
////////////////////////////////////////////////////////////////////////////////
/// @brief escape html /// @brief escape html
////////////////////////////////////////////////////////////////////////////////
std::string escapeHtml(std::string const& name); std::string escapeHtml(std::string const& name);
////////////////////////////////////////////////////////////////////////////////
/// @brief escape xml /// @brief escape xml
////////////////////////////////////////////////////////////////////////////////
std::string escapeXml(std::string const& name); std::string escapeXml(std::string const& name);
////////////////////////////////////////////////////////////////////////////////
/// @brief escape hex for all non-printable characters (including space) /// @brief escape hex for all non-printable characters (including space)
////////////////////////////////////////////////////////////////////////////////
std::string escapeHex(std::string const& name, char quote = '%'); std::string escapeHex(std::string const& name, char quote = '%');
////////////////////////////////////////////////////////////////////////////////
/// @brief escape hex /// @brief escape hex
////////////////////////////////////////////////////////////////////////////////
std::string escapeHex(std::string const& name, std::string const& specials, std::string escapeHex(std::string const& name, std::string const& specials,
char quote = '%'); char quote = '%');
////////////////////////////////////////////////////////////////////////////////
/// @brief escape as C code /// @brief escape as C code
////////////////////////////////////////////////////////////////////////////////
std::string escapeC(std::string const& name); std::string escapeC(std::string const& name);
////////////////////////////////////////////////////////////////////////////////
/// @brief splits a string /// @brief splits a string
////////////////////////////////////////////////////////////////////////////////
std::vector<std::string> split(std::string const& source, char delim = ',', std::vector<std::string> split(std::string const& source, char delim = ',',
char quote = '\\'); char quote = '\\');
////////////////////////////////////////////////////////////////////////////////
/// @brief splits a string /// @brief splits a string
////////////////////////////////////////////////////////////////////////////////
std::vector<std::string> split(std::string const& source, std::vector<std::string> split(std::string const& source,
std::string const& delim, char quote = '\\'); std::string const& delim, char quote = '\\');
////////////////////////////////////////////////////////////////////////////////
/// @brief joins a string /// @brief joins a string
////////////////////////////////////////////////////////////////////////////////
template <typename C> template <typename C>
std::string join(C const& source, std::string const& delim = ",") { std::string join(C const& source, std::string const& delim = ",") {
std::string result; std::string result;
@ -203,183 +149,102 @@ std::string join(C const& source, char delim = ',') {
return result; return result;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief removes leading and trailing whitespace /// @brief removes leading and trailing whitespace
////////////////////////////////////////////////////////////////////////////////
std::string trim(std::string const& sourceStr, std::string trim(std::string const& sourceStr,
std::string const& trimStr = " \t\n\r"); std::string const& trimStr = " \t\n\r");
////////////////////////////////////////////////////////////////////////////////
/// @brief removes leading and trailing whitespace in place /// @brief removes leading and trailing whitespace in place
////////////////////////////////////////////////////////////////////////////////
void trimInPlace(std::string& str, std::string const& trimStr = " \t\n\r"); void trimInPlace(std::string& str, std::string const& trimStr = " \t\n\r");
////////////////////////////////////////////////////////////////////////////////
/// @brief removes leading whitespace /// @brief removes leading whitespace
////////////////////////////////////////////////////////////////////////////////
std::string lTrim(std::string const& sourceStr, std::string lTrim(std::string const& sourceStr,
std::string const& trimStr = " \t\n\r"); std::string const& trimStr = " \t\n\r");
////////////////////////////////////////////////////////////////////////////////
/// @brief removes trailing whitespace /// @brief removes trailing whitespace
////////////////////////////////////////////////////////////////////////////////
std::string rTrim(std::string const& sourceStr, std::string rTrim(std::string const& sourceStr,
std::string const& trimStr = " \t\n\r"); std::string const& trimStr = " \t\n\r");
void rTrimInPlace(std::string& str, std::string const& trimStr = " \t\n\r"); void rTrimInPlace(std::string& str, std::string const& trimStr = " \t\n\r");
////////////////////////////////////////////////////////////////////////////////
/// @brief fills string from left /// @brief fills string from left
////////////////////////////////////////////////////////////////////////////////
std::string lFill(std::string const& sourceStr, size_t size, char fill = ' '); std::string lFill(std::string const& sourceStr, size_t size, char fill = ' ');
////////////////////////////////////////////////////////////////////////////////
/// @brief fills string from right /// @brief fills string from right
////////////////////////////////////////////////////////////////////////////////
std::string rFill(std::string const& sourceStr, size_t size, char fill = ' '); std::string rFill(std::string const& sourceStr, size_t size, char fill = ' ');
////////////////////////////////////////////////////////////////////////////////
/// @brief wrap longs lines /// @brief wrap longs lines
////////////////////////////////////////////////////////////////////////////////
std::vector<std::string> wrap(std::string const& sourceStr, size_t size, std::vector<std::string> wrap(std::string const& sourceStr, size_t size,
std::string const& breaks = " "); std::string const& breaks = " ");
////////////////////////////////////////////////////////////////////////////////
/// @brief substring replace /// @brief substring replace
////////////////////////////////////////////////////////////////////////////////
std::string replace(std::string const& sourceStr, std::string const& fromString, std::string replace(std::string const& sourceStr, std::string const& fromString,
std::string const& toString); std::string const& toString);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts string to lower case in place /// @brief converts string to lower case in place
////////////////////////////////////////////////////////////////////////////////
void tolowerInPlace(std::string* str); void tolowerInPlace(std::string* str);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts string to lower case /// @brief converts string to lower case
////////////////////////////////////////////////////////////////////////////////
std::string tolower(std::string&& str); std::string tolower(std::string&& str);
std::string tolower(std::string const& str); std::string tolower(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts string to upper case in place /// @brief converts string to upper case in place
////////////////////////////////////////////////////////////////////////////////
void toupperInPlace(std::string* str); void toupperInPlace(std::string* str);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts string to upper case /// @brief converts string to upper case
////////////////////////////////////////////////////////////////////////////////
std::string toupper(std::string const& str); std::string toupper(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks for a prefix /// @brief checks for a prefix
////////////////////////////////////////////////////////////////////////////////
bool isPrefix(std::string const& str, std::string const& prefix); bool isPrefix(std::string const& str, std::string const& prefix);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks for a suffix /// @brief checks for a suffix
////////////////////////////////////////////////////////////////////////////////
bool isSuffix(std::string const& str, std::string const& postfix); bool isSuffix(std::string const& str, std::string const& postfix);
////////////////////////////////////////////////////////////////////////////////
/// @brief url decodes the string /// @brief url decodes the string
////////////////////////////////////////////////////////////////////////////////
std::string urlDecodePath(std::string const& str); std::string urlDecodePath(std::string const& str);
std::string urlDecode(std::string const& str); std::string urlDecode(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief url encodes the string /// @brief url encodes the string
////////////////////////////////////////////////////////////////////////////////
std::string urlEncode(char const* src); std::string urlEncode(char const* src);
////////////////////////////////////////////////////////////////////////////////
/// @brief url encodes the string /// @brief url encodes the string
////////////////////////////////////////////////////////////////////////////////
std::string urlEncode(char const* src, size_t const len); std::string urlEncode(char const* src, size_t const len);
////////////////////////////////////////////////////////////////////////////////
/// @brief unicode hexidecmial characters to utf8 /// @brief unicode hexidecmial characters to utf8
////////////////////////////////////////////////////////////////////////////////
bool unicodeToUTF8(char const* inputStr, size_t const& len, bool unicodeToUTF8(char const* inputStr, size_t const& len,
std::string& outputStr); std::string& outputStr);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts an utf16 symbol which needs UTF16 to UTF8 /// @brief converts an utf16 symbol which needs UTF16 to UTF8
/// The conversion correspond to the specification: /// The conversion correspond to the specification:
/// http://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B10000_to_U.2B10FFFF /// http://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B10000_to_U.2B10FFFF
////////////////////////////////////////////////////////////////////////////////
bool convertUTF16ToUTF8(char const* high_surrogate, char const* low_surrogate, bool convertUTF16ToUTF8(char const* high_surrogate, char const* low_surrogate,
std::string& outputStr); std::string& outputStr);
////////////////////////////////////////////////////////////////////////////////
/// @brief url encodes the string /// @brief url encodes the string
////////////////////////////////////////////////////////////////////////////////
std::string urlEncode(std::string const& str); std::string urlEncode(std::string const& str);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// CONVERT TO STRING // CONVERT TO STRING
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief converts integer to string /// @brief converts integer to string
////////////////////////////////////////////////////////////////////////////////
std::string itoa(int16_t i); std::string itoa(int16_t i);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts unsigned integer to string /// @brief converts unsigned integer to string
////////////////////////////////////////////////////////////////////////////////
std::string itoa(uint16_t i); std::string itoa(uint16_t i);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts integer to string /// @brief converts integer to string
////////////////////////////////////////////////////////////////////////////////
std::string itoa(int64_t i); std::string itoa(int64_t i);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts unsigned integer to string /// @brief converts unsigned integer to string
////////////////////////////////////////////////////////////////////////////////
std::string itoa(uint64_t i); std::string itoa(uint64_t i);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts integer to string /// @brief converts integer to string
////////////////////////////////////////////////////////////////////////////////
std::string itoa(int32_t i); std::string itoa(int32_t i);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts unsigned integer to string /// @brief converts unsigned integer to string
////////////////////////////////////////////////////////////////////////////////
std::string itoa(uint32_t i); std::string itoa(uint32_t i);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts size_t to string /// @brief converts size_t to string
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_OVERLOAD_FUNCS_SIZE_T #ifdef TRI_OVERLOAD_FUNCS_SIZE_T
#if TRI_SIZEOF_SIZE_T == 4 #if TRI_SIZEOF_SIZE_T == 4
@ -394,20 +259,14 @@ inline std::string itoa(size_t i) { return itoa(uint64_t(i)); }
#endif #endif
////////////////////////////////////////////////////////////////////////////////
/// @brief converts decimal to string /// @brief converts decimal to string
////////////////////////////////////////////////////////////////////////////////
std::string ftoa(double i); std::string ftoa(double i);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// CONVERT FROM STRING // CONVERT FROM STRING
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a single hex to integer /// @brief converts a single hex to integer
////////////////////////////////////////////////////////////////////////////////
inline int hex2int(char ch, int errorValue = 0) { inline int hex2int(char ch, int errorValue = 0) {
if ('0' <= ch && ch <= '9') { if ('0' <= ch && ch <= '9') {
return ch - '0'; return ch - '0';
@ -420,173 +279,108 @@ inline int hex2int(char ch, int errorValue = 0) {
return errorValue; return errorValue;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a boolean /// @brief parses a boolean
////////////////////////////////////////////////////////////////////////////////
bool boolean(std::string const& str); bool boolean(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses an integer /// @brief parses an integer
////////////////////////////////////////////////////////////////////////////////
int64_t int64(std::string const& str); int64_t int64(std::string const& str);
inline int64_t int64(char const* value, size_t size) { inline int64_t int64(char const* value, size_t size) {
return StringUtils::int64(std::string(value, size)); return StringUtils::int64(std::string(value, size));
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief parses an unsigned integer /// @brief parses an unsigned integer
////////////////////////////////////////////////////////////////////////////////
uint64_t uint64(std::string const& str); uint64_t uint64(std::string const& str);
inline uint64_t uint64(char const* value, size_t size) { inline uint64_t uint64(char const* value, size_t size) {
return StringUtils::uint64(std::string(value, size)); return StringUtils::uint64(std::string(value, size));
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief parses an unsigned integer /// @brief parses an unsigned integer
/// the caller must make sure that the input buffer only contains valid /// the caller must make sure that the input buffer only contains valid
/// numeric characters - otherwise the uint64_t result will be wrong. /// numeric characters - otherwise the uint64_t result will be wrong.
/// because the input is restricted to some valid characters, this function /// because the input is restricted to some valid characters, this function
/// is highly optimized /// is highly optimized
////////////////////////////////////////////////////////////////////////////////
uint64_t uint64_trusted(char const* value, size_t length); uint64_t uint64_trusted(char const* value, size_t length);
inline uint64_t uint64_trusted(std::string const& value) { inline uint64_t uint64_trusted(std::string const& value) {
return uint64_trusted(value.c_str(), value.size()); return uint64_trusted(value.c_str(), value.size());
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief parses an integer /// @brief parses an integer
////////////////////////////////////////////////////////////////////////////////
int32_t int32(std::string const& str); int32_t int32(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses an integer /// @brief parses an integer
////////////////////////////////////////////////////////////////////////////////
int32_t int32(char const* value, size_t size); int32_t int32(char const* value, size_t size);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses an unsigned integer /// @brief parses an unsigned integer
////////////////////////////////////////////////////////////////////////////////
uint32_t uint32(std::string const& str); uint32_t uint32(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses an unsigned integer /// @brief parses an unsigned integer
////////////////////////////////////////////////////////////////////////////////
uint32_t uint32(char const* value, size_t size); uint32_t uint32(char const* value, size_t size);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses an unsigned integer given in HEX /// @brief parses an unsigned integer given in HEX
////////////////////////////////////////////////////////////////////////////////
uint32_t unhexUint32(std::string const& str); uint32_t unhexUint32(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses an unsigned integer given in HEX /// @brief parses an unsigned integer given in HEX
////////////////////////////////////////////////////////////////////////////////
uint32_t unhexUint32(char const* value, size_t size); uint32_t unhexUint32(char const* value, size_t size);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a decimal /// @brief parses a decimal
////////////////////////////////////////////////////////////////////////////////
double doubleDecimal(std::string const& str); double doubleDecimal(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a decimal /// @brief parses a decimal
////////////////////////////////////////////////////////////////////////////////
double doubleDecimal(char const* value, size_t size); double doubleDecimal(char const* value, size_t size);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a decimal /// @brief parses a decimal
////////////////////////////////////////////////////////////////////////////////
float floatDecimal(std::string const& str); float floatDecimal(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a decimal /// @brief parses a decimal
////////////////////////////////////////////////////////////////////////////////
float floatDecimal(char const* value, size_t size); float floatDecimal(char const* value, size_t size);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// BASE64 // BASE64
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief converts to base64 /// @brief converts to base64
////////////////////////////////////////////////////////////////////////////////
std::string encodeBase64(std::string const&); std::string encodeBase64(std::string const&);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts from base64 /// @brief converts from base64
////////////////////////////////////////////////////////////////////////////////
std::string decodeBase64(std::string const&); std::string decodeBase64(std::string const&);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts to base64, URL friendly /// @brief converts to base64, URL friendly
/// ///
/// '-' and '_' are used instead of '+' and '/' /// '-' and '_' are used instead of '+' and '/'
////////////////////////////////////////////////////////////////////////////////
std::string encodeBase64U(std::string const&); std::string encodeBase64U(std::string const&);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts from base64, URL friendly /// @brief converts from base64, URL friendly
/// ///
/// '-' and '_' are used instead of '+' and '/' /// '-' and '_' are used instead of '+' and '/'
////////////////////////////////////////////////////////////////////////////////
std::string decodeBase64U(std::string const&); std::string decodeBase64U(std::string const&);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// ADDITIONAL STRING UTILITIES // ADDITIONAL STRING UTILITIES
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief replaces incorrect path delimiter character for window and linux /// @brief replaces incorrect path delimiter character for window and linux
////////////////////////////////////////////////////////////////////////////////
std::string correctPath(std::string const& incorrectPath); std::string correctPath(std::string const& incorrectPath);
////////////////////////////////////////////////////////////////////////////////
/// @brief finds n.th entry /// @brief finds n.th entry
////////////////////////////////////////////////////////////////////////////////
std::string entry(size_t const pos, std::string const& sourceStr, std::string entry(size_t const pos, std::string const& sourceStr,
std::string const& delimiter = ","); std::string const& delimiter = ",");
////////////////////////////////////////////////////////////////////////////////
/// @brief counts number of entires /// @brief counts number of entires
////////////////////////////////////////////////////////////////////////////////
size_t numEntries(std::string const& sourceStr, size_t numEntries(std::string const& sourceStr,
std::string const& delimiter = ","); std::string const& delimiter = ",");
////////////////////////////////////////////////////////////////////////////////
/// @brief converts to hex /// @brief converts to hex
//////////////////////////////////////////////////////////////////////////////// std::string encodeHex(char const* value, size_t length);
std::string encodeHex(std::string const& value);
std::string encodeHex(std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts from hex /// @brief converts from hex
//////////////////////////////////////////////////////////////////////////////// /// any invalid character in the input sequence will make the function return
/// an empty string
std::string decodeHex(std::string const& str); std::string decodeHex(char const* value, size_t length);
std::string decodeHex(std::string const& value);
bool gzipUncompress(char const* compressed, size_t compressedLength, bool gzipUncompress(char const* compressed, size_t compressedLength,
std::string& uncompressed); std::string& uncompressed);

View File

@ -568,74 +568,6 @@ void TRI_FreeString(char* value) {
TRI_Free(value); TRI_Free(value);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief converts into hex representation
////////////////////////////////////////////////////////////////////////////////
char* TRI_EncodeHexString(char const* source, size_t sourceLen,
size_t* dstLen) {
char* result;
uint16_t* hex;
uint16_t* dst;
uint8_t* src;
size_t j;
*dstLen = (sourceLen * 2);
dst = static_cast<uint16_t*>(
TRI_Allocate((*dstLen) + 1));
if (dst == nullptr) {
return nullptr;
}
result = (char*)dst;
hex = (uint16_t*)HexValues;
src = (uint8_t*)source;
for (j = 0; j < sourceLen; j++) {
*dst = hex[*src];
dst++;
src++;
}
*((char*)dst) = 0; // terminate the string
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts from hex representation
////////////////////////////////////////////////////////////////////////////////
char* TRI_DecodeHexString(char const* source, size_t sourceLen,
size_t* dstLen) {
char* result;
uint8_t* dst;
uint8_t* src;
size_t j;
*dstLen = (sourceLen / 2);
dst = static_cast<uint8_t*>(
TRI_Allocate((*dstLen) + 1));
if (dst == nullptr) {
return nullptr;
}
result = (char*)dst;
src = (uint8_t*)source;
for (j = 0; j < sourceLen; j += 2) {
uint8_t d;
d = HexDecodeLookup[*src++] << 4;
d |= HexDecodeLookup[*src++];
*dst++ = d;
}
*dst = 0; // terminate the string
return result;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief sha256 of a string /// @brief sha256 of a string
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1003,38 +935,6 @@ char* TRI_UnescapeUtf8String(char const* in,
return buffer; return buffer;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief determine the number of characters in a UTF-8 string
/// the UTF-8 string must be well-formed and end with a NUL terminator
////////////////////////////////////////////////////////////////////////////////
size_t TRI_CharLengthUtf8String(char const* in) {
unsigned char const* p = reinterpret_cast<unsigned char const*>(in);
size_t chars = 0;
while (*p) {
unsigned char c = *p;
if (c < 128) {
// single byte
p++;
} else if (c < 224) {
p += 2;
} else if (c < 240) {
p += 3;
} else if (c < 248) {
p += 4;
} else {
// invalid UTF-8 sequence
break;
}
++chars;
}
return chars;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief determine the number of characters in a UTF-8 string /// @brief determine the number of characters in a UTF-8 string
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -120,18 +120,6 @@ char* TRI_Concatenate3String(char const*, char const*,
void TRI_FreeString(char*); void TRI_FreeString(char*);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts into hex representation
////////////////////////////////////////////////////////////////////////////////
char* TRI_EncodeHexString(char const* source, size_t sourceLen, size_t* dstLen);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts from hex representation
////////////////////////////////////////////////////////////////////////////////
char* TRI_DecodeHexString(char const* source, size_t sourceLen, size_t* dstLen);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief sha256 of a string /// @brief sha256 of a string
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -186,13 +174,6 @@ char* TRI_EscapeUtf8String(char const* in, size_t inLength,
char* TRI_UnescapeUtf8String(char const* in, char* TRI_UnescapeUtf8String(char const* in,
size_t inLength, size_t* outLength, bool normalize); size_t inLength, size_t* outLength, bool normalize);
////////////////////////////////////////////////////////////////////////////////
/// @brief determine the number of characters in a UTF-8 string
/// the UTF-8 string must be well-formed and end with a NUL terminator
////////////////////////////////////////////////////////////////////////////////
size_t TRI_CharLengthUtf8String(char const*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief determine the number of characters in a UTF-8 string /// @brief determine the number of characters in a UTF-8 string
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -223,15 +223,13 @@ std::string sslPBKDF2HS1(char const* salt, size_t saltLength, char const* pass,
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
} }
TRI_DEFER(TRI_Free(dk));
PKCS5_PBKDF2_HMAC_SHA1(pass, (int)passLength, (const unsigned char*)salt, PKCS5_PBKDF2_HMAC_SHA1(pass, (int)passLength, (const unsigned char*)salt,
(int)saltLength, iter, keyLength, dk); (int)saltLength, iter, keyLength, dk);
// return value as hex // return value as hex
std::string result = return StringUtils::encodeHex((char*)dk, keyLength);
StringUtils::encodeHex(std::string((char*)dk, keyLength));
TRI_Free(dk);
return result;
} }
std::string sslPBKDF2(char const* salt, size_t saltLength, char const* pass, std::string sslPBKDF2(char const* salt, size_t saltLength, char const* pass,
@ -258,16 +256,14 @@ std::string sslPBKDF2(char const* salt, size_t saltLength, char const* pass,
if (dk == nullptr) { if (dk == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
} }
TRI_DEFER(TRI_Free(dk));
PKCS5_PBKDF2_HMAC(pass, (int)passLength, (const unsigned char*)salt, PKCS5_PBKDF2_HMAC(pass, (int)passLength, (const unsigned char*)salt,
(int)saltLength, iter, evp_md, keyLength, dk); (int)saltLength, iter, evp_md, keyLength, dk);
// return value as hex // return value as hex
std::string result = return StringUtils::encodeHex((char*)dk, keyLength);
StringUtils::encodeHex(std::string((char*)dk, keyLength));
TRI_Free(dk);
return result;
} }
std::string sslHMAC(char const* key, size_t keyLength, char const* message, std::string sslHMAC(char const* key, size_t keyLength, char const* message,
@ -294,15 +290,14 @@ std::string sslHMAC(char const* key, size_t keyLength, char const* message,
if (md == nullptr) { if (md == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
} }
TRI_DEFER(TRI_Free(md));
unsigned int md_len; unsigned int md_len;
HMAC(evp_md, key, (int)keyLength, (const unsigned char*)message, messageLen, HMAC(evp_md, key, (int)keyLength, (const unsigned char*)message, messageLen,
md, &md_len); md, &md_len);
std::string result = std::string((char*)md, md_len); return std::string((char*)md, md_len);
TRI_Free(md);
return result;
} }
bool verifyHMAC(char const* challenge, size_t challengeLength, bool verifyHMAC(char const* challenge, size_t challengeLength,

View File

@ -3453,8 +3453,10 @@ static void JS_HMAC(v8::FunctionCallbackInfo<v8::Value> const& args) {
} }
} }
std::string result = StringUtils::encodeHex(SslInterface::sslHMAC( std::string v = SslInterface::sslHMAC(
key.c_str(), key.size(), message.c_str(), message.size(), al)); key.c_str(), key.size(), message.c_str(), message.size(), al);
std::string result = StringUtils::encodeHex(v.data(), v.size());
TRI_V8_RETURN_STD_STRING(result); TRI_V8_RETURN_STD_STRING(result);
TRI_V8_TRY_CATCH_END TRI_V8_TRY_CATCH_END
} }

View File

@ -231,12 +231,107 @@ SECTION("test_uint64_trusted") {
CHECK(UINT64_MAX == StringUtils::uint64_trusted(std::to_string(UINT64_MAX))); CHECK(UINT64_MAX == StringUtils::uint64_trusted(std::to_string(UINT64_MAX)));
} }
//////////////////////////////////////////////////////////////////////////////// SECTION("test_encodeHex") {
/// @brief generate tests CHECK("" == StringUtils::encodeHex(""));
////////////////////////////////////////////////////////////////////////////////
CHECK("00" == StringUtils::encodeHex(std::string("\x00", 1)));
CHECK("01" == StringUtils::encodeHex("\x01"));
CHECK("02" == StringUtils::encodeHex("\x02"));
CHECK("03" == StringUtils::encodeHex("\x03"));
CHECK("04" == StringUtils::encodeHex("\x04"));
CHECK("05" == StringUtils::encodeHex("\x05"));
CHECK("06" == StringUtils::encodeHex("\x06"));
CHECK("07" == StringUtils::encodeHex("\x07"));
CHECK("08" == StringUtils::encodeHex("\x08"));
CHECK("09" == StringUtils::encodeHex("\x09"));
CHECK("0a" == StringUtils::encodeHex("\x0a"));
CHECK("0b" == StringUtils::encodeHex("\x0b"));
CHECK("0c" == StringUtils::encodeHex("\x0c"));
CHECK("0d" == StringUtils::encodeHex("\x0d"));
CHECK("0e" == StringUtils::encodeHex("\x0e"));
CHECK("0f" == StringUtils::encodeHex("\x0f"));
CHECK("10" == StringUtils::encodeHex("\x10"));
CHECK("42" == StringUtils::encodeHex("\x42"));
CHECK("ff" == StringUtils::encodeHex("\xff"));
CHECK("aa0009" == StringUtils::encodeHex(std::string("\xaa\x00\x09", 3)));
CHECK("000102" == StringUtils::encodeHex(std::string("\x00\x01\x02", 3)));
CHECK("00010203" == StringUtils::encodeHex(std::string("\x00\x01\x02\03", 4)));
CHECK("20" == StringUtils::encodeHex(" "));
CHECK("2a2a" == StringUtils::encodeHex("**"));
CHECK("616263646566" == StringUtils::encodeHex("abcdef"));
CHECK("4142434445462047" == StringUtils::encodeHex("ABCDEF G"));
CHECK("54686520517569636b2062726f776e20466f78206a756d706564206f76657220746865206c617a7920646f6721" == StringUtils::encodeHex("The Quick brown Fox jumped over the lazy dog!"));
CHECK("446572204bc3b674c3b67220737072c3bc6e6720c3bc62657220646965204272c3bc636b65" == StringUtils::encodeHex("Der Kötör sprüng über die Brücke"));
CHECK("c3a4c3b6c3bcc39fc384c396c39ce282acc2b5" == StringUtils::encodeHex("äöüßÄÖÜ€µ"));
}
SECTION("test_decodeHex") {
CHECK("" == StringUtils::decodeHex(""));
CHECK(std::string("\x00", 1) == StringUtils::decodeHex("00"));
CHECK("\x01" == StringUtils::decodeHex("01"));
CHECK("\x02" == StringUtils::decodeHex("02"));
CHECK("\x03" == StringUtils::decodeHex("03"));
CHECK("\x04" == StringUtils::decodeHex("04"));
CHECK("\x05" == StringUtils::decodeHex("05"));
CHECK("\x06" == StringUtils::decodeHex("06"));
CHECK("\x07" == StringUtils::decodeHex("07"));
CHECK("\x08" == StringUtils::decodeHex("08"));
CHECK("\x09" == StringUtils::decodeHex("09"));
CHECK("\x0a" == StringUtils::decodeHex("0a"));
CHECK("\x0b" == StringUtils::decodeHex("0b"));
CHECK("\x0c" == StringUtils::decodeHex("0c"));
CHECK("\x0d" == StringUtils::decodeHex("0d"));
CHECK("\x0e" == StringUtils::decodeHex("0e"));
CHECK("\x0f" == StringUtils::decodeHex("0f"));
CHECK("\x0a" == StringUtils::decodeHex("0A"));
CHECK("\x0b" == StringUtils::decodeHex("0B"));
CHECK("\x0c" == StringUtils::decodeHex("0C"));
CHECK("\x0d" == StringUtils::decodeHex("0D"));
CHECK("\x0e" == StringUtils::decodeHex("0E"));
CHECK("\x0f" == StringUtils::decodeHex("0F"));
CHECK("\x1a" == StringUtils::decodeHex("1a"));
CHECK("\x2b" == StringUtils::decodeHex("2b"));
CHECK("\x3c" == StringUtils::decodeHex("3c"));
CHECK("\x4d" == StringUtils::decodeHex("4d"));
CHECK("\x5e" == StringUtils::decodeHex("5e"));
CHECK("\x6f" == StringUtils::decodeHex("6f"));
CHECK("\x7a" == StringUtils::decodeHex("7A"));
CHECK("\x8b" == StringUtils::decodeHex("8B"));
CHECK("\x9c" == StringUtils::decodeHex("9C"));
CHECK("\xad" == StringUtils::decodeHex("AD"));
CHECK("\xbe" == StringUtils::decodeHex("BE"));
CHECK("\xcf" == StringUtils::decodeHex("CF"));
CHECK("\xdf" == StringUtils::decodeHex("df"));
CHECK("\xef" == StringUtils::decodeHex("eF"));
CHECK("\xff" == StringUtils::decodeHex("ff"));
CHECK(" " == StringUtils::decodeHex("20"));
CHECK("**" == StringUtils::decodeHex("2a2a"));
CHECK("abcdef" == StringUtils::decodeHex("616263646566"));
CHECK("ABCDEF G" == StringUtils::decodeHex("4142434445462047"));
CHECK("The Quick brown Fox jumped over the lazy dog!" == StringUtils::decodeHex("54686520517569636b2062726f776e20466f78206a756d706564206f76657220746865206c617a7920646f6721"));
CHECK("Der Kötör sprüng über die Brücke" == StringUtils::decodeHex("446572204bc3b674c3b67220737072c3bc6e6720c3bc62657220646965204272c3bc636b65"));
CHECK("äöüßÄÖÜ€µ" == StringUtils::decodeHex("c3a4c3b6c3bcc39fc384c396c39ce282acc2b5"));
CHECK("" == StringUtils::decodeHex("1"));
CHECK("" == StringUtils::decodeHex(" "));
CHECK("" == StringUtils::decodeHex(" 2"));
CHECK("" == StringUtils::decodeHex("1 "));
CHECK("" == StringUtils::decodeHex("12 "));
CHECK("" == StringUtils::decodeHex("x"));
CHECK("" == StringUtils::decodeHex("X"));
CHECK("" == StringUtils::decodeHex("@@@"));
CHECK("" == StringUtils::decodeHex("111"));
CHECK("" == StringUtils::decodeHex("1 2 3"));
CHECK("" == StringUtils::decodeHex("1122334"));
CHECK("" == StringUtils::decodeHex("112233 "));
CHECK("" == StringUtils::decodeHex(" 112233"));
CHECK("" == StringUtils::decodeHex("abcdefgh"));
}
} }
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:

View File

@ -387,7 +387,7 @@ SECTION("tst_western_european") {
SECTION("tst_char_length") { SECTION("tst_char_length") {
const char* test = "დახმარებისთვის"; const char* test = "დახმარებისთვის";
CHECK((14) == (int) TRI_CharLengthUtf8String(test)); CHECK((14) == (int) TRI_CharLengthUtf8String(test, strlen(test)));
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////