Created
October 31, 2012 18:42
-
-
Save crowell/3989008 to your computer and use it in GitHub Desktop.
Safety in the process file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cstring> | |
#include <cstdio> | |
#include <string> | |
#include <map> | |
#include "getpost.h" | |
#include <sys/resource.h> | |
using namespace std; | |
// CONSTANTS | |
char text[5000]; /* The text supplied by the user. */ | |
int length; /* The length supplied by the user. */ | |
int TOP_NUM; /* The number of entries to show the user. */ | |
// CLASSES | |
class cStringMap { | |
// implements a map from C-style strings to integers | |
public: | |
int& operator[](char *key) { return data[key];} | |
char *topValue() { | |
static char *result; | |
map<char *,int>::iterator iter; | |
int maxSeen = -1; | |
for (iter = data.begin(); iter != data.end(); iter++) | |
if (iter->second > maxSeen) { // I found a value bigger than maxSeen | |
maxSeen = iter->second; // record the value | |
result = iter->first; // record the key that produced the value | |
} | |
return result; | |
} | |
void print() { | |
map<char *,int>::iterator iter; | |
for (iter = data.begin(); iter != data.end(); iter++) | |
cout << iter->first << ": " << iter->second << endl; | |
cout << endl; | |
} | |
private: | |
class cmp_str { // a class for comparing C-style strings | |
public: | |
bool operator()(char *a, char *b) { return strcmp(a,b) < 0; } | |
}; | |
map<char *,int, cmp_str> data; | |
}; | |
// FUNCTIONS | |
char **topValues(cStringMap &patterns) { | |
// Returns the TOP_NUM keys with the highest values in <patterns> | |
char **top_entries = new char *[TOP_NUM]; | |
char tmp[TOP_NUM]; | |
for (int ii=0; ii<TOP_NUM; ii++) { | |
strcpy(tmp,patterns.topValue()); | |
top_entries[ii]=patterns.topValue(); // extract the key with the largest value | |
patterns[tmp]*=-1; // make the value small so that we do not choose it again | |
} | |
// fix all negative numbers so that they are positive again, as they were initially | |
for (int ii=0; ii<TOP_NUM; ii++) | |
patterns[top_entries[ii]]*=-1; | |
return top_entries; | |
} | |
void parse(cStringMap& patterns, int len, char *text) { | |
/** Records in <patterns> the substrings of length <len> in <text>, and how often they appear. */ | |
for (int ii=0; ii<strlen(text) - len + 1; ii++) { | |
char *substring = new char[len+1]; | |
strncpy(substring,text+ii,len); // copy a piece of <text> into <substring> SAFE with strncpy | |
substring[len] = 0; //SAFE null terminate it | |
patterns[substring]++; // tally this substring as seen | |
} | |
} | |
int main() | |
{ | |
// initialize | |
map<string,string> Get; // parameters from the server | |
cStringMap patterns; // patterns found in the text provided | |
TOP_NUM = 10; | |
//If this is run on the command line, uncomment the next line. | |
setenv("QUERY_STRING","len=1&text=AAABBJ",1); | |
initializeGet(Get); | |
length = atoi(Get["len"].c_str()); // the length inputted by the user | |
strncpy(text,Get["text"].c_str(),4999); // the text inputted by the user Made safe with strncpy | |
//begin safe checks | |
if(length <=0) | |
{ | |
cout << "nice try..." << endl; | |
cout << "length must be greater than 0" << endl; | |
return 1; | |
} | |
if(length > strlen(text)) | |
{ | |
cout << "nice try..." << endl; | |
cout << "length must not be longer than text" << endl; | |
return 1; | |
} | |
//end safe checks | |
// set some limits on resource usage | |
rlimit lim = {10,10}; | |
setrlimit(RLIMIT_CPU,&lim); | |
// output the web page | |
cout <<"Content-type: text/html"<<endl<<endl; | |
cout << "<h1>" << TOP_NUM << " most common patterns of length " << length | |
<< ":</h1><pre>" << endl; | |
// populate the patterns class | |
parse(patterns, length, text); | |
// get the top TOP_NUM values | |
char **result = topValues(patterns); | |
// display the top values | |
char* myString = new char[length]; | |
for (int ii=0; ii<TOP_NUM; ii++) | |
{ | |
if(ii != 0) | |
{ | |
if(strncmp(result[ii], myString, length) == 0) | |
{ | |
break; | |
} | |
} | |
cout << result[ii] << ": " <<patterns[result[ii]] << "<BR>" << endl; | |
strncpy(myString,result[ii], length); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment