I have the following mockup that I need some feedback on how I might improve the url_decode
function to make it faster and use less memory. There are a couple of requirements. I have to use the StringArg
and StringReturn
structs. I also need to completely decode the string. I am aware of double encoded attacks, but this is for data mining and I need to get the string fully decoded, hence the while loop.
Please have a look at function StringReturn* url_decode(char* line)
and suggest anything that I can do to improve the speed or reduce the memory used.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <ctype.h>
struct StringArg
{
int length;
char* data;
StringArg(const char* inData)
{
length = strlen(inData);
data = new char[length+1];
strcpy(data, inData);
}
};
struct StringReturn
{
int size;
char* data;
StringReturn(int inSize)
{
size = inSize;
data = new char[size+1];
}
};
StringArg* stringArg(char* line)
{
return new StringArg(line);
}
StringReturn* stringReturnInfo(int size)
{
return new StringReturn(size);
}
StringReturn* url_decode(char* line)
{
StringArg *str;
str = stringArg(line);
int lengths = str->length;
char* urlData = new char[lengths+1];
char* fmt = new char[4];
memcpy(urlData, str->data, str->length);
urlData[lengths] = 0;
bool bFoundChar = false;
int j = 0;
do
{
j = 0;
bFoundChar = false;
for (int i = 0; i < lengths; i++)
{
char ch = urlData[i];
if (ch == '+')
{
urlData[j++] = ' ';
}
else if (ch == '%' && i+2 < lengths && isxdigit(urlData[i+1]) && isxdigit(urlData[i+2]))
{
bFoundChar = true;
fmt = new char[4];
fmt[0] = urlData[++i];
fmt[1] = urlData[++i];
fmt[2] = 0;
urlData[j++] = (char)strtol(fmt, NULL, 16);
}
else {
urlData[j++] = ch;
}
}
lengths = j;
}while (bFoundChar);
StringReturn *ret = stringReturnInfo(j);
ret->size = j;
memcpy(ret->data, urlData, j);
delete urlData;
delete fmt;
return ret;
}
void test_decode(char* line)
{
StringReturn *str = url_decode(line);
printf(str->data);
}
int main(int argc, const char * argv[])
{
test_decode("bob.com?url=http%3A%2F%2Fsteve.com%3Furl%3Dhttp%253A%252F%252Fjohn.com");
return 0;
}