aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2021-09-18 23:10:23 +0200
committerJohn Ankarström <john@ankarstrom.se>2021-09-18 23:11:23 +0200
commit7708b5f493bf3057af331624d29664ad17a87dbc (patch)
treebe56e078c043b7338938507d048307e851249726
parent9ff1b81d65c370a938cd9d9c033e04e395f00704 (diff)
downloadcforum-7708b5f493bf3057af331624d29664ad17a87dbc.tar.gz
Make nextparam work with non-NUL-terminated data
At least on POST.
-rw-r--r--README8
-rw-r--r--cforum.c2
-rw-r--r--ctl.c37
-rw-r--r--query.c22
-rw-r--r--query.h3
-rw-r--r--site.h2
6 files changed, 41 insertions, 33 deletions
diff --git a/README b/README
index 8030d7f..9472b04 100644
--- a/README
+++ b/README
@@ -9,14 +9,14 @@ It is also rather small:
wc -l *.c *.h */*.t */*.lex
101 cforum.c
- 223 ctl.c
+ 222 ctl.c
268 db.c
10 err.c
- 113 query.c
+ 121 query.c
6 ctl.h
40 db.h
0 err.h
- 14 query.h
+ 15 query.h
21 site.h
3 t/err.t
1 t/foot.t
@@ -26,4 +26,4 @@ It is also rather small:
28 t/post.t
12 t/user.t
95 mktpl/mktpl.lex
- 1012 total
+ 1020 total
diff --git a/cforum.c b/cforum.c
index feee431..999ae78 100644
--- a/cforum.c
+++ b/cforum.c
@@ -73,7 +73,7 @@ main(int argc, char *argv[])
/* Parse query string. */
new = NULL;
attid = postid = userid = 0;
- while(p = nextparam(GET, 128)){
+ while(p = nextparam(GET, NULL, 128)){
v = split(p);
if(!attid && strcmp(p, "att") == 0) attid = atoi(v);
else if(!postid && strcmp(p, "post") == 0) postid = atoi(v);
diff --git a/ctl.c b/ctl.c
index e4b25a7..712b31a 100644
--- a/ctl.c
+++ b/ctl.c
@@ -37,12 +37,9 @@ newpost()
void
newuser()
{
- char *confirm, *hlite, *msg, *name, *full, *p, *pass, *v;
+ char *confirm, *hlite, msg[128], *name, *full, *p, *pass, *v;
char title[] = "New User";
- if(!(msg = malloc(128)))
- err(1, "malloc");
-
*msg = 0;
confirm = hlite = name = full = pass = NULL;
@@ -52,7 +49,15 @@ newuser()
return;
}
- while(p = nextparam(POST, MAXUSERPARAM)){
+ if(query.length > MAXUSERDATA){
+ snprintf(msg, 128, "Input exceeded server limitations");
+ printf("Status: 431 Request Header Fields Too Large\n");
+ printf("Content-Type: text/html\n\n");
+ #include "t/newuser.tc"
+ return;
+ }
+
+ while(p = nextparam(POST, NULL, MAXUSERDATA)){
if(!(v = split(p))) continue;
if(!confirm && strcmp(p, "confirm") == 0)
@@ -65,20 +70,6 @@ newuser()
pass = strdup(v);
else
continue;
-
- if(TRUNCATED(p)){
- hlite = strdup(p);
- snprintf(msg, 128,
- "Input length exceeds server limitations");
- goto err;
- }
- }
-
- /* Ensure all required fields are there. */
- if(!name || !*name || !pass || !*pass){
- hlite = (!name || !*name)? strdup("name"): strdup("pass");
- snprintf(msg, 128, "Required field missing");
- goto err;
}
/* Decode URL-encoded fields. */
@@ -103,6 +94,13 @@ newuser()
goto err;
}
+ /* Ensure all required fields are there. */
+ if(!name || !*name || !pass || !*pass){
+ hlite = (!name || !*name)? strdup("name"): strdup("pass");
+ snprintf(msg, 128, "Required field missing");
+ goto err;
+ }
+
if(pass && confirm && strcmp(pass, confirm) != 0){
snprintf(msg, 128, "Passwords do not match");
goto err;
@@ -112,6 +110,7 @@ newuser()
printf("You are valid\n");
return;
err:
+ printf("Status: 400 Bad Request\n");
printf("Content-Type: text/html\n\n");
#include "t/newuser.tc"
return;
diff --git a/query.c b/query.c
index 370fa54..27770e4 100644
--- a/query.c
+++ b/query.c
@@ -5,14 +5,19 @@
#include "query.h"
/*
- * Return an allocated string containing the next query string parameter
- * ("key=value"). The string is truncated to max characters (but is always
- * NUL-terminated). If truncation occurred, the -1th character of the string
- * is set to 1.
+ * Return an allocated string containing the next parameter ("key=value").
+ * The method argument decides which data (GET or POST) to read from.
+ *
+ * If len is NULL, the string will be NUL-terminated; if len is non-NULL,
+ * the string will not be NUL-terminated, and len will be pointed to the
+ * length of the string.
+ *
+ * The string is truncated to max characters. If truncation occurred, the
+ * -1th character of the string is set to 1.
*/
char *
-nextparam(enum method method, int max)
-{
+nextparam(enum method method, int *len, int max)
+{
char *buf;
int i, sz;
static int j = 0;
@@ -73,7 +78,8 @@ rest:
err(1, "realloc");
}
}
- buf[i] = 0;
+ if(len) *len = i;
+ else buf[i] = 0;
return buf;
}
@@ -88,6 +94,8 @@ setquery()
exit(1);
}
query.method = strcmp(getenv("REQUEST_METHOD"), "POST")? GET: POST;
+ if(query.method == POST)
+ query.length = atoi(getenv("CONTENT_LENGTH"));
}
/*
diff --git a/query.h b/query.h
index a5cb168..6a4c1cc 100644
--- a/query.h
+++ b/query.h
@@ -2,6 +2,7 @@
struct query{
int method;
+ int length; /* Content length. */
char *string;
} query;
@@ -10,6 +11,6 @@ enum method{
POST
};
-char *nextparam(enum method, int);
+char *nextparam(enum method, int *, int);
void setquery(void);
char *split(char *); \ No newline at end of file
diff --git a/site.h b/site.h
index 4e13319..800cdea 100644
--- a/site.h
+++ b/site.h
@@ -13,7 +13,7 @@
#define MAXUSERPARAM 512
/* Maximum size of user information, incl. NUL. */
-#define MAXUSERNAME 80
+#define MAXUSERNAME 40
#define MAXUSERFULL 128
#define MAXUSERPASS 128