|
/* |
|
* cookie parsing algorithms for ModSecurity3 |
|
* |
|
* g++ -O0 -g cookieparse.cpp -o cookieparse |
|
* |
|
* ./cookieparse " key1= foo ; key2=bar=apple; key3 = peach,orange; key 4 = banane ; key5" |
|
*/ |
|
#include <iostream> |
|
#include <vector> |
|
#include <sstream> |
|
|
|
// copied from src/utils/string.cc |
|
std::vector<std::string> ssplit(std::string str, char delimiter) { |
|
std::vector<std::string> internal; |
|
std::stringstream ss(str); // Turn the string into a stream. |
|
std::string tok; |
|
ssize_t n = str.length(); |
|
int i = 0; |
|
|
|
while (getline(ss, tok, delimiter)) { |
|
n -= tok.length(); |
|
if (i > 0) n--; |
|
internal.push_back(n == 1 ? tok + delimiter : tok); |
|
i++; |
|
} |
|
|
|
return internal; |
|
} |
|
|
|
// copied from src/utils/string.cc |
|
std::vector<std::string> split(std::string str, char delimiter) { |
|
std::vector<std::string> internal = ssplit(str, delimiter); |
|
|
|
if (internal.size() == 0) { |
|
internal.push_back(str); |
|
} |
|
|
|
return internal; |
|
} |
|
|
|
// new method, setting of variable just marked |
|
int method_new(std::string &value) { |
|
std::string value2 = value; |
|
|
|
size_t localOffset = 0; |
|
size_t pos1, pos2; |
|
for(pos1 = 0; pos1 < value.length(); pos1++) { |
|
value2[pos1] = ' '; |
|
} |
|
std::vector<std::string> cookies = ssplit(value, ';'); |
|
for (const std::string &c : cookies) { |
|
pos1 = c.find_first_of("=", 0); |
|
|
|
std::string ckey = ""; |
|
std::string cval = ""; |
|
|
|
if (pos1 == std::string::npos) { |
|
ckey = c; |
|
} |
|
else { |
|
ckey = c.substr(0, pos1); |
|
cval = c.substr(pos1+1, c.length()); |
|
} |
|
|
|
// remove leading spaces |
|
while (ckey.length() > 0 && ckey.at(0) == ' ') { |
|
ckey.erase(0, 1); |
|
localOffset++; |
|
} |
|
// replace remained spaces with underscore |
|
// eg " foo bar = foobar" -> "foo_bar= foobar" |
|
pos2 = 0; |
|
while(ckey.length() > 0 && pos2 < ckey.length()) { |
|
if (ckey.at(pos2) == ' ') { |
|
ckey.replace(pos2, 1, "_"); |
|
} |
|
pos2++; |
|
} |
|
// set cookie name, localOffset... |
|
value2[localOffset] = '^'; |
|
localOffset = localOffset + ckey.length() + 1; |
|
// if cval != '' set cookie value, localOffset... |
|
if (cval != "") { |
|
value2[localOffset] = '^'; |
|
localOffset = localOffset + cval.length() + 1; |
|
} |
|
|
|
} |
|
std::cout << value << "\n"; |
|
std::cout << value2 << "\n"; |
|
return 0; |
|
} |
|
|
|
// original method, setting of variable commented out |
|
int method_orig(std::string &value) { |
|
size_t localOffset = 0; |
|
std::string value2 = value; |
|
|
|
size_t pos1; |
|
for(pos1 = 0; pos1 < value.length(); pos1++) { |
|
value2[pos1] = ' '; |
|
} |
|
|
|
std::vector<std::string> cookies = ssplit(value, ';'); |
|
for (const std::string &c : cookies) { |
|
std::vector<std::string> s = split(c, |
|
'='); |
|
if (s.size() > 1) { |
|
if (s[0].at(0) == ' ') { |
|
s[0].erase(0, 1); |
|
} |
|
//m_variableRequestCookiesNames.set(s[0], |
|
// s[0], localOffset); |
|
value2[localOffset] = '^'; |
|
localOffset = localOffset + s[0].size() + 1; |
|
//m_variableRequestCookies.set(s[0], s[1], localOffset); |
|
value2[localOffset] = '^'; |
|
localOffset = localOffset + s[1].size() + 2; |
|
} |
|
} |
|
std::cout << value << "\n"; |
|
std::cout << value2 << "\n"; |
|
return 0; |
|
} |
|
|
|
|
|
int main(int argc, char* argv[]) { |
|
|
|
std::string value = ""; |
|
if (argc > 1) { |
|
value = argv[1]; |
|
} |
|
else { |
|
value = " key1= foo ; key2=bar=apple; key3 = peach,orange; key 4 = banane ; key5"; |
|
} |
|
|
|
method_orig(value); |
|
std::cout << "======\n"; |
|
method_new(value); |
|
|
|
return 0; |
|
} |