12#include <boost/algorithm/string/classification.hpp>
13#include <boost/algorithm/string/constants.hpp>
14#include <boost/algorithm/string/split.hpp>
44 while ((pos = name.find(
'\\', pos)) != std::string::npos) {
53trim(
const string& instring) {
54 string retstring =
"";
55 if (!instring.empty()) {
56 static const char* blanks =
" \t\n";
59 size_t first = instring.find_first_not_of(blanks);
60 if (first != string::npos) {
63 size_t last = instring.find_last_not_of(blanks);
66 retstring = instring.substr(first, (last - first + 1));
77tokens(
const std::string& text,
const std::string& delim,
bool escape) {
78 vector<string> result;
80 bool in_token =
false;
82 for (
auto c = text.cbegin(); c != text.cend(); ++c) {
83 if (delim.find(*c) != string::npos) {
94 result.push_back(token);
100 }
else if (escape && (*c ==
'\\')) {
123 token.push_back(
'\\');
134 token.push_back(
'\\');
136 if (!token.empty()) {
137 result.push_back(token);
148lengthSum(string::size_type curlen,
const string& cur_string) {
149 return (curlen + cur_string.size());
157format(
const std::string&
format,
const std::vector<std::string>& args) {
159 static const string flag =
"%s";
166 size_t length = accumulate(args.begin(), args.end(),
format.size(),
167 lengthSum) - (args.size() * flag.size());
168 result.reserve(length);
173 std::vector<std::string>::size_type i = 0;
175 while ((i < args.size()) && (tokenpos != string::npos)) {
176 tokenpos = result.find(flag, tokenpos);
177 if (tokenpos != string::npos) {
178 result.replace(tokenpos, flag.size(), args[i++]);
189 if (iss.bad() || iss.fail()) {
197 std::vector<uint8_t> binary;
199 std::string trimmed_string =
trim(quoted_string);
203 if ((trimmed_string.length() > 1) && ((trimmed_string[0] ==
'\'') &&
204 (trimmed_string[trimmed_string.length()-1] ==
'\''))) {
206 trimmed_string =
trim(trimmed_string.substr(1, trimmed_string.length() - 2));
208 binary.assign(trimmed_string.begin(), trimmed_string.end());
216 std::vector<uint8_t>& binary) {
222 std::vector<uint8_t>& binary) {
223 std::vector<std::string> split_text;
224 boost::split(split_text, hex_string, boost::is_any_of(sep),
225 boost::algorithm::token_compress_off);
227 std::vector<uint8_t> binary_vec;
228 for (
size_t i = 0; i < split_text.size(); ++i) {
233 if ((split_text.size() > 1) && split_text[i].empty()) {
235 " a decoded string '" << hex_string <<
"'");
238 }
else if (split_text[i].size() > 2) {
240 <<
" '" << hex_string <<
"'");
242 }
else if (!split_text[i].empty()) {
246 for (
unsigned int j = 0; j < split_text[i].length(); ++j) {
248 if (!isxdigit(split_text[i][j])) {
250 <<
"' is not a valid hexadecimal digit in"
251 <<
" decoded string '" << hex_string <<
"'");
253 s << split_text[i][j];
259 unsigned int binary_value;
260 s >> std::hex >> binary_value;
262 binary_vec.push_back(
static_cast<uint8_t
>(binary_value));
268 binary.swap(binary_vec);
274 std::vector<uint8_t>& binary) {
277 if (hex_string.find(
':') != std::string::npos) {
279 }
else if (hex_string.find(
' ') != std::string::npos) {
282 std::ostringstream s;
285 if (hex_string.length() % 2 != 0) {
290 if ((hex_string.length() > 2) && (hex_string.substr(0, 2) ==
"0x")) {
292 s << hex_string.substr(2);
305 " string of hexadecimal digits");
314 : char_set_(char_set), char_replacement_(char_replacement) {
317 <<
"' exceeds max size: '"
323 << char_replacement.size() <<
"' exceeds max size: '"
328 scrub_exp_ = std::regex(char_set, std::regex::extended);
329 }
catch (
const std::exception& ex) {
331 << char_set_ <<
"', " << ex.what());
334 int ec = regcomp(&scrub_exp_, char_set_.c_str(), REG_EXTENDED);
336 char errbuf[512] =
"";
337 static_cast<void>(regerror(ec, &scrub_exp_, errbuf,
sizeof(errbuf)));
338 regfree(&scrub_exp_);
347 regfree(&scrub_exp_);
351 std::string
scrub(
const std::string& original) {
353 std::stringstream result;
355 std::regex_replace(std::ostream_iterator<char>(result),
356 original.begin(), original.end(),
357 scrub_exp_, char_replacement_);
358 }
catch (
const std::exception& ex) {
360 << char_replacement_ <<
"' in '" << original <<
"' failed: ,"
364 return (result.str());
369 const char* orig_data = original.data();
370 const char* dead_end = orig_data + original.size();
371 const char* start_from = orig_data;
374 while (start_from < dead_end) {
376 regmatch_t matches[2];
377 const char* end_at = start_from + strlen(start_from);
379 while (start_from < end_at) {
381 if (regexec(&scrub_exp_, start_from, 1, matches, 0) == REG_NOMATCH) {
383 result << start_from;
384 start_from = end_at + 1;
389 if (matches[0].rm_so == -1) {
394 const char* match_at = start_from + matches[0].rm_so;
395 while (start_from < match_at) {
396 result << *start_from;
401 result << char_replacement_;
408 if (start_from < dead_end) {
410 result << char_replacement_;
411 start_from = end_at + 1;
415 return (result.str());
421 std::string char_set_;
424 std::string char_replacement_;
439 const std::string& char_replacement)
448 return (impl_->scrub(original));
451std::string
dumpAsHex(
const uint8_t* data,
size_t length) {
452 std::stringstream output;
453 for (
unsigned int i = 0; i < length; i++) {
458 output << std::setfill(
'0') << std::setw(2) << std::hex
459 <<
static_cast<unsigned short>(data[i]);
462 return (output.str());
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown when an unexpected error condition occurs.
~StringSanitizerImpl()
Destructor.
StringSanitizerImpl(const std::string &char_set, const std::string &char_replacement)
Constructor.
std::string scrub(const std::string &original)
std::string scrub(const std::string &original)
Returns a scrubbed copy of a given string.
~StringSanitizer()
Destructor.
static const uint32_t MAX_DATA_SIZE
The maximum size for regex parameters.
StringSanitizer(const std::string &char_set, const std::string &char_replacement)
Constructor.
A Set of C++ Utilities for Manipulating Strings.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
void decodeHex(const string &input, vector< uint8_t > &result)
Decode a text encoded in the base16 ('hex') format into the original data.
void normalizeSlash(std::string &name)
Normalize Backslash.
std::string format(const std::string &format, const std::vector< std::string > &args)
Apply Formatting.
std::string dumpAsHex(const uint8_t *data, size_t length)
Dumps a buffer of bytes as a string of hexadecimal digits.
std::string getToken(std::istringstream &iss)
Returns one token from the given stringstream.
void decodeSeparatedHexString(const std::string &hex_string, const std::string &sep, std::vector< uint8_t > &binary)
Converts a string of separated hexadecimal digits into a vector.
void decodeFormattedHexString(const std::string &hex_string, std::vector< uint8_t > &binary)
Converts a formatted string of hexadecimal digits into a vector.
std::vector< uint8_t > quotedStringToBinary(const std::string "ed_string)
Converts a string in quotes into vector.
void decodeColonSeparatedHexString(const std::string &hex_string, std::vector< uint8_t > &binary)
Converts a string of hexadecimal digits with colons into a vector.
string trim(const string &instring)
Trim Leading and Trailing Spaces.
vector< string > tokens(const std::string &text, const std::string &delim, bool escape)
Split String into Tokens.
Defines the logger used by the top-level component of kea-lfc.