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) {
217 std::vector<std::string> split_text;
218 boost::split(split_text, hex_string, boost::is_any_of(
":"),
219 boost::algorithm::token_compress_off);
221 std::vector<uint8_t> binary_vec;
222 for (
size_t i = 0; i < split_text.size(); ++i) {
227 if ((split_text.size() > 1) && split_text[i].empty()) {
229 " a decoded string '" << hex_string <<
"'");
232 }
else if (split_text[i].size() > 2) {
234 <<
" '" << hex_string <<
"'");
236 }
else if (!split_text[i].empty()) {
240 for (
unsigned int j = 0; j < split_text[i].length(); ++j) {
242 if (!isxdigit(split_text[i][j])) {
244 <<
"' is not a valid hexadecimal digit in"
245 <<
" decoded string '" << hex_string <<
"'");
247 s << split_text[i][j];
253 unsigned int binary_value;
254 s >> std::hex >> binary_value;
256 binary_vec.push_back(
static_cast<uint8_t
>(binary_value));
262 binary.swap(binary_vec);
267 std::vector<uint8_t>& binary) {
270 if (hex_string.find(
':') != std::string::npos) {
274 std::ostringstream s;
277 if (hex_string.length() % 2 != 0) {
282 if ((hex_string.length() > 2) && (hex_string.substr(0, 2) ==
"0x")) {
284 s << hex_string.substr(2);
297 " string of hexadecimal digits");
305 : char_set_(char_set), char_replacement_(char_replacement) {
308 scrub_exp_ = std::regex(char_set, std::regex::extended);
309 }
catch (
const std::exception& ex) {
311 << char_set_ <<
"', " << ex.
what());
314 int ec = regcomp(&scrub_exp_, char_set_.c_str(), REG_EXTENDED);
316 char errbuf[512] =
"";
317 static_cast<void>(regerror(ec, &scrub_exp_, errbuf,
sizeof(errbuf)));
318 regfree(&scrub_exp_);
327 regfree(&scrub_exp_);
331 std::string
scrub(
const std::string& original) {
333 std::stringstream result;
335 std::regex_replace(std::ostream_iterator<char>(result),
336 original.begin(), original.end(),
337 scrub_exp_, char_replacement_);
338 }
catch (
const std::exception& ex) {
340 << char_replacement_ <<
"' in '" << original <<
"' failed: ,"
344 return (result.str());
347 const char* origStr = original.c_str();
348 const char* startFrom = origStr;
349 const char* endAt = origStr + strlen(origStr);
350 regmatch_t matches[2];
353 while (startFrom < endAt) {
355 if (regexec(&scrub_exp_, startFrom, 1, matches, 0) == REG_NOMATCH) {
362 if (matches[0].rm_so == -1) {
367 const char* matchAt = startFrom + matches[0].rm_so;
368 while (startFrom < matchAt) {
369 result << *startFrom;
374 result << char_replacement_;
380 return (result.str());
385 std::string char_set_;
386 std::string char_replacement_;
395 StringSanitizer::StringSanitizer(
const std::string& char_set,
396 const std::string& char_replacement)
406 return (impl_->
scrub(original));