12 #include <boost/algorithm/string/classification.hpp>
13 #include <boost/algorithm/string/constants.hpp>
14 #include <boost/algorithm/string/split.hpp>
26 #include <sys/types.h>
44 while ((pos = name.find(
'\\', pos)) != std::string::npos) {
53 trim(
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));
77 tokens(
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);
148 lengthSum(string::size_type curlen,
const string& cur_string) {
149 return (curlen + cur_string.size());
157 format(
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");
313 : char_set_(char_set), char_replacement_(char_replacement) {
314 if (char_set.size() > StringSanitizer::MAX_DATA_SIZE) {
316 <<
"' exceeds max size: '"
317 << StringSanitizer::MAX_DATA_SIZE <<
"'");
320 if (char_replacement.size() > StringSanitizer::MAX_DATA_SIZE) {
322 << char_replacement.size() <<
"' exceeds max size: '"
323 << StringSanitizer::MAX_DATA_SIZE <<
"'");
327 scrub_exp_ = std::regex(char_set, std::regex::extended);
328 }
catch (
const std::exception& ex) {
330 << char_set_ <<
"', " << ex.
what());
333 int ec = regcomp(&scrub_exp_, char_set_.c_str(), REG_EXTENDED);
335 char errbuf[512] =
"";
336 static_cast<void>(regerror(ec, &scrub_exp_, errbuf,
sizeof(errbuf)));
337 regfree(&scrub_exp_);
346 regfree(&scrub_exp_);
350 std::string
scrub(
const std::string& original) {
352 std::stringstream result;
354 std::regex_replace(std::ostream_iterator<char>(result),
355 original.begin(), original.end(),
356 scrub_exp_, char_replacement_);
357 }
catch (
const std::exception& ex) {
359 << char_replacement_ <<
"' in '" << original <<
"' failed: ,"
363 return (result.str());
368 const char* orig_data = original.data();
369 const char* dead_end = orig_data + original.size();
370 const char* start_from = orig_data;
373 while (start_from < dead_end) {
375 regmatch_t matches[2];
376 const char* end_at = start_from + strlen(start_from);
378 while (start_from < end_at) {
380 if (regexec(&scrub_exp_, start_from, 1, matches, 0) == REG_NOMATCH) {
382 result << start_from;
383 start_from = end_at + 1;
388 if (matches[0].rm_so == -1) {
393 const char* match_at = start_from + matches[0].rm_so;
394 while (start_from < match_at) {
395 result << *start_from;
400 result << char_replacement_;
407 if (start_from < dead_end) {
409 result << char_replacement_;
410 start_from = end_at + 1;
414 return (result.str());
420 std::string char_set_;
423 std::string char_replacement_;
435 const uint32_t StringSanitizer::MAX_DATA_SIZE = 4096;
437 StringSanitizer::StringSanitizer(
const std::string& char_set,
438 const std::string& char_replacement)
448 return (impl_->
scrub(original));
~StringSanitizer()
Destructor.
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.
~StringSanitizerImpl()
Destructor.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
std::string scrub(const std::string &original)
void decodeHex(const string &input, vector< uint8_t > &result)
Decode a text encoded in the base16 ('hex') format into the original data.
A generic exception that is thrown when an unexpected error condition occurs.
std::string getToken(std::istringstream &iss)
Returns one token from the given stringstream.
void normalizeSlash(std::string &name)
Normalize Backslash.
vector< string > tokens(const std::string &text, const std::string &delim, bool escape)
Split String into Tokens.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A Set of C++ Utilities for Manipulating Strings.
std::vector< uint8_t > quotedStringToBinary(const std::string "ed_string)
Converts a string in quotes into vector.
Defines the logger used by the top-level component of kea-dhcp-ddns.
void decodeColonSeparatedHexString(const std::string &hex_string, std::vector< uint8_t > &binary)
Converts a string of hexadecimal digits with colons into a vector.
std::string scrub(const std::string &original)
Returns a scrubbed copy of a given string.
string trim(const string &instring)
Trim Leading and Trailing Spaces.
StringSanitizerImpl(const std::string &char_set, const std::string &char_replacement)
std::string format(const std::string &format, const std::vector< std::string > &args)
Apply Formatting.