diff --git a/htdocs/archive/addfile.c b/htdocs/archive/addfile.c index c1734622c..e54a2c7ab 100644 --- a/htdocs/archive/addfile.c +++ b/htdocs/archive/addfile.c @@ -35,12 +35,14 @@ int main() const char *query_string = getenv("QUERY_STRING"); if (query_string == NULL) { generatepage("Internal error: empty/invalid data"); - } else if (strlen(query_string) > 1024) { - generatepage("Internal error: data size limit exceeded (1024)"); + } else if (strlen(query_string) > MAX_LINE_LEN) { + char errmsg[100] = {0}; + sprintf(errmsg, "Internal error: data size limit exceeded (%i)", MAX_LINE_LEN); + generatepage(errmsg); } else if (NULL != validate(query_string)) { generatepage(validate(query_string)); } else { - char data[4096] = {0}; + char data[MAX_LINE_LEN] = {0}; unencode(query_string, data); if (NULL != validate(data)) { diff --git a/htdocs/archive/deletefile.c b/htdocs/archive/deletefile.c index 72d74f6a5..d9e441d83 100644 --- a/htdocs/archive/deletefile.c +++ b/htdocs/archive/deletefile.c @@ -25,7 +25,7 @@ int main() } sortdata(data, MAX_RECORDS); - char name[32] = {0}; + char name[MAX_NAME_LEN] = {0}; strcpy(name, getname(query_string)); int index = -1; for (int i = 0; i < MAX_RECORDS && data[i]; i++) { diff --git a/htdocs/archive/edit.c b/htdocs/archive/edit.c index 4366f28ac..ae1726154 100644 --- a/htdocs/archive/edit.c +++ b/htdocs/archive/edit.c @@ -25,7 +25,7 @@ int main() return EXIT_SUCCESS; } - char name[32] = {0}; + char name[MAX_NAME_LEN] = {0}; strcpy(name, getname(query_string)); int index = -1; for (int i = 0; i < MAX_RECORDS && data[i]; i++) { diff --git a/htdocs/archive/report.c b/htdocs/archive/report.c index 5a6a63fbd..e89f7373f 100644 --- a/htdocs/archive/report.c +++ b/htdocs/archive/report.c @@ -83,7 +83,7 @@ int main() if (query_string == NULL || *query_string == '\0') { listAll(data); } else if (strncmp(query_string, "name=", 5) == 0 && getname(query_string) != NULL) { - char name[32] = {0}; + char name[MAX_NAME_LEN] = {0}; strcpy(name, getname(query_string)); listOne(data,name); } else { diff --git a/htdocs/archive/setfiledata.c b/htdocs/archive/setfiledata.c index a05ffa463..77e936fd9 100644 --- a/htdocs/archive/setfiledata.c +++ b/htdocs/archive/setfiledata.c @@ -24,7 +24,7 @@ int main() return EXIT_SUCCESS; } - char name[32] = {0}; + char name[MAX_NAME_LEN] = {0}; strcpy(name, getname(query_string)); int index = -1; for (int i = 0; i < MAX_RECORDS && data[i]; i++) { @@ -40,7 +40,7 @@ int main() } // cleanup data... - char str[1000] = {0}; + char str[MAX_LINE_LEN] = {0}; char *dst = str; for (const char *src = query_string; *src; src++) { *dst = *src; diff --git a/htdocs/archive/webarchive.h b/htdocs/archive/webarchive.h index ae4ccdd07..92830b720 100644 --- a/htdocs/archive/webarchive.h +++ b/htdocs/archive/webarchive.h @@ -1,7 +1,11 @@ #include #include +#include +#include -#define MAX_RECORDS 1000 +#define MAX_RECORDS 1000 +#define MAX_LINE_LEN 0xffff +#define MAX_NAME_LEN 32 static void unencode(const char *src, char *dest) { @@ -12,6 +16,10 @@ static void unencode(const char *src, char *dest) int code; if (sscanf(src+1, "%2x", &code) != 1) code = '?'; + if (code == '%' && isxdigit(src[3]) && isxdigit(src[4])) { + src += 2; + sscanf(src+1, "%2x", &code); + } *dest = code; src += 2; } else @@ -26,7 +34,7 @@ int readdata(char * * const data, int sz) if (!f) return 0; // failed - char line[10000] = {0}; + char line[MAX_LINE_LEN] = {0}; int i = 0; while (i < sz && fgets(line,sizeof(line)-2,f)) { if (strncmp(line, "name=", 5) == 0) { @@ -163,6 +171,44 @@ const char *validate_name_version_data(const char *data) // filedata if (strncmp(data+i, "&data=", 6) != 0) return "invalid query string: 'data=' not seen at the expected location"; + i += 6; + + // validate xml + char xml[strlen(data+i)]; + memset(xml, 0, strlen(data+i)); + unencode(data+i, xml); + + if (strncmp(xml,"",21)!=0) + return "invalid query string: XML must start with '<?xml version=\"1.0\"?>'"; + int linenr = 1; + enum {TEXT,ELEMENT} state = TEXT; + for (int pos = 21; xml[pos]; pos++) { + if (strncmp(&xml[pos], "\r\n", 2)==0) { + ++linenr; + ++pos; + } else if (xml[pos]=='\r' || xml[pos]=='\n') { + ++linenr; + } else if (xml[pos] == '<') { + if (state != TEXT) { + static char errmsg[256]; + sprintf(errmsg, "invalid query string: Invalid XML at line %i", linenr); + return errmsg; + } + state = ELEMENT; + } else if (xml[pos] == '>') { + if (state != ELEMENT) { + static char errmsg[256]; + sprintf(errmsg, "invalid query string: Invalid XML at line %i", linenr); + return errmsg; + } + state = TEXT; + } + } + if (state != TEXT) { + static char errmsg[256]; + sprintf(errmsg, "invalid query string: Invalid XML at line %i", linenr); + return errmsg; + } return NULL; }