webarchive: updated validation

This commit is contained in:
Daniel Marjamäki 2013-07-21 11:27:50 +02:00
parent f11e54aa42
commit 6e7c29987d
6 changed files with 58 additions and 10 deletions

View File

@ -35,12 +35,14 @@ int main()
const char *query_string = getenv("QUERY_STRING"); const char *query_string = getenv("QUERY_STRING");
if (query_string == NULL) { if (query_string == NULL) {
generatepage("Internal error: empty/invalid data"); generatepage("Internal error: empty/invalid data");
} else if (strlen(query_string) > 1024) { } else if (strlen(query_string) > MAX_LINE_LEN) {
generatepage("Internal error: data size limit exceeded (1024)"); char errmsg[100] = {0};
sprintf(errmsg, "Internal error: data size limit exceeded (%i)", MAX_LINE_LEN);
generatepage(errmsg);
} else if (NULL != validate(query_string)) { } else if (NULL != validate(query_string)) {
generatepage(validate(query_string)); generatepage(validate(query_string));
} else { } else {
char data[4096] = {0}; char data[MAX_LINE_LEN] = {0};
unencode(query_string, data); unencode(query_string, data);
if (NULL != validate(data)) { if (NULL != validate(data)) {

View File

@ -25,7 +25,7 @@ int main()
} }
sortdata(data, MAX_RECORDS); sortdata(data, MAX_RECORDS);
char name[32] = {0}; char name[MAX_NAME_LEN] = {0};
strcpy(name, getname(query_string)); strcpy(name, getname(query_string));
int index = -1; int index = -1;
for (int i = 0; i < MAX_RECORDS && data[i]; i++) { for (int i = 0; i < MAX_RECORDS && data[i]; i++) {

View File

@ -25,7 +25,7 @@ int main()
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
char name[32] = {0}; char name[MAX_NAME_LEN] = {0};
strcpy(name, getname(query_string)); strcpy(name, getname(query_string));
int index = -1; int index = -1;
for (int i = 0; i < MAX_RECORDS && data[i]; i++) { for (int i = 0; i < MAX_RECORDS && data[i]; i++) {

View File

@ -83,7 +83,7 @@ int main()
if (query_string == NULL || *query_string == '\0') { if (query_string == NULL || *query_string == '\0') {
listAll(data); listAll(data);
} else if (strncmp(query_string, "name=", 5) == 0 && getname(query_string) != NULL) { } 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)); strcpy(name, getname(query_string));
listOne(data,name); listOne(data,name);
} else { } else {

View File

@ -24,7 +24,7 @@ int main()
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
char name[32] = {0}; char name[MAX_NAME_LEN] = {0};
strcpy(name, getname(query_string)); strcpy(name, getname(query_string));
int index = -1; int index = -1;
for (int i = 0; i < MAX_RECORDS && data[i]; i++) { for (int i = 0; i < MAX_RECORDS && data[i]; i++) {
@ -40,7 +40,7 @@ int main()
} }
// cleanup data... // cleanup data...
char str[1000] = {0}; char str[MAX_LINE_LEN] = {0};
char *dst = str; char *dst = str;
for (const char *src = query_string; *src; src++) { for (const char *src = query_string; *src; src++) {
*dst = *src; *dst = *src;

View File

@ -1,7 +1,11 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#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) static void unencode(const char *src, char *dest)
{ {
@ -12,6 +16,10 @@ static void unencode(const char *src, char *dest)
int code; int code;
if (sscanf(src+1, "%2x", &code) != 1) if (sscanf(src+1, "%2x", &code) != 1)
code = '?'; code = '?';
if (code == '%' && isxdigit(src[3]) && isxdigit(src[4])) {
src += 2;
sscanf(src+1, "%2x", &code);
}
*dest = code; *dest = code;
src += 2; src += 2;
} else } else
@ -26,7 +34,7 @@ int readdata(char * * const data, int sz)
if (!f) if (!f)
return 0; // failed return 0; // failed
char line[10000] = {0}; char line[MAX_LINE_LEN] = {0};
int i = 0; int i = 0;
while (i < sz && fgets(line,sizeof(line)-2,f)) { while (i < sz && fgets(line,sizeof(line)-2,f)) {
if (strncmp(line, "name=", 5) == 0) { if (strncmp(line, "name=", 5) == 0) {
@ -163,6 +171,44 @@ const char *validate_name_version_data(const char *data)
// filedata // filedata
if (strncmp(data+i, "&data=", 6) != 0) if (strncmp(data+i, "&data=", 6) != 0)
return "invalid query string: 'data=' not seen at the expected location"; 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,"<?xml version=\"1.0\"?>",21)!=0)
return "invalid query string: XML must start with '&lt;?xml version=\"1.0\"?&gt;'";
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; return NULL;
} }