commit 67a8b26aba9217eb68ec5c1e04765b85c7b33a5c
parent 3f8a18907d21e9e1a91799243d0ec86d5f948bd0
Author: quantumish <freifeld.david@gmail.com>
Date: Sun, 16 Apr 2023 00:34:35 -0700
Fix double free() bug
Diffstat:
3 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/http.c b/http.c
@@ -47,9 +47,9 @@ char* get_file_ext(char* filename) {
return ext;
}
-response_t serve_file(request_t req) {
+response_t serve_file(request_t* req) {
char path[128+8] = "./public";
- strcat(path, req.path);
+ strcat(path, req->path);
int fd = open(path, O_RDONLY); // TODO handle
response_t r = resp_new(OK);
@@ -59,14 +59,14 @@ response_t serve_file(request_t req) {
for (size_t i = 0; read(fd, fbuf+(i*4096), 4096) > 0; i++);
- char* ext = get_file_ext(req.path);
+ char* ext = get_file_ext(req->path);
resp_set_ctype(&r, ext);
bool ok = true;
char* mtype = (char*)ext_to_mtype(ext);
char* hdr;
- if ((hdr = hashmap_get(&req.headers, "Accept"))) {
+ if ((hdr = hashmap_get(&req->headers, "Accept"))) {
ok = false;
shitvec_t mtypes = hdr_parse_accept(hdr);
for (int j = 0; j < mtypes.vec_sz; j++) {
@@ -82,7 +82,7 @@ response_t serve_file(request_t req) {
char* buf = fbuf; // buffer to be written
size_t bufsize = st.st_size;
- if (ok && (hdr = hashmap_get(&req.headers, "Accept-Encoding"))) {
+ if (ok && (hdr = hashmap_get(&req->headers, "Accept-Encoding"))) {
ok = false;
shitvec_t mtypes = hdr_parse_accept(hdr); // abuse of this func
for (int j = 0; j < mtypes.vec_sz; j++) {
@@ -119,26 +119,25 @@ response_t serve_file(request_t req) {
// TODO actually respect requests
// TODO list dirs
-response_t make_response (request_t req) {
- if (req_parse(&req) < 0) {
+response_t make_response (request_t* req) {
+ if (req_parse(req) < 0) {
log_error("Failed to parse incoming request.");
return serve_error(BadRequest);
}
/* hashmap_dump(&req.headers); */
- log_info("Got request %s %s", method_name(req.method), req.path);
+ log_info("Got request %s %s", method_name(req->method), req->path);
- char* mapped_path = hashmap_get(&path_redirs, req.path);
+ char* mapped_path = hashmap_get(&path_redirs, req->path);
if (mapped_path != NULL) {
- log_debug("test");
- strcpy(req.path, mapped_path);
+ strcpy(req->path, mapped_path);
}
- if (!shitvec_check(&paths, req.path, (sv_cmp_t)strcmp)) {
+ if (!shitvec_check(&paths, req->path, (sv_cmp_t)strcmp)) {
return serve_error(NotFound);
}
- switch (req.method) {
+ switch (req->method) {
case GET: return serve_file(req); break;
default: return serve_error(MethodNotAllowed);
}
@@ -158,9 +157,8 @@ void* handle_conn(void* ctxt) {
gettimeofday(&before, NULL);
if (msgbuf[0] != 0) {
request_t req = req_new(msgbuf, 1024);
- log_debug("after init %p %p", req.headers.keys, req.headers.vals);
- response_t r = make_response(req);
+ response_t r = make_response(&req);
send(ns, r.content, r.sz, 0);
free(r.content);
@@ -240,7 +238,6 @@ int main() {
pthread_create(&lthread, NULL, listen_for_conns, &s);
while (true) {
int ns = *(int*)channel_recv(&listen_chan);
- log_debug("%d", ns);
pthread_t thread;
pthread_create(&thread, NULL, handle_conn, &ns);
diff --git a/http/request.c b/http/request.c
@@ -17,6 +17,9 @@ enum http_method method_enum(char* p) {
return method_codes[((*(uint64_t*)p*0x1b8b6e6d) % 0x100000000) >> 28];
}
+// Be careful about passing by value! if the internal hashmap resizes
+// a req_free() call on the original (the one copied *from*) will be a
+// double free() error
request_t req_new(char* reqbuf, size_t bufsize) {
request_t req;
req.buf = reqbuf;
diff --git a/utils/hashmap.c b/utils/hashmap.c
@@ -41,7 +41,6 @@ hashmap_t hashmap_new(size_t ksize, size_t vsize) {
// Keys and vals are in different arrays so unnecessary things aren't in cache
h.keys = calloc(HASHMAP_INIT_SIZE, ksize);
h.vals = malloc(vsize * HASHMAP_INIT_SIZE);
- log_debug("in init %p %p", h.keys, h.vals);
h.k_sz = ksize;
h.v_sz = vsize;
h.len = HASHMAP_INIT_SIZE;
@@ -66,7 +65,7 @@ void hashmap_resize(hashmap_t* h) {
h->len *= 2;
// Simple to use calloc here because keys need to be initialized to zero.
h->keys = calloc(h->len, h->k_sz);
- h->vals = malloc(h->len * h->v_sz);
+ h->vals = malloc(h->len * h->v_sz);
// Copy all keys and values
for (size_t off = 0; off < (h->len / 2); off++) {
// Don't bother copying entries with empty keys
@@ -89,7 +88,6 @@ void hashmap_dump(hashmap_t* h) {
int hashmap_set(hashmap_t* h, void* k, void* v) {
// Check if load factor too high
-
if ((float)h->filled / h->len > (float)2/3) hashmap_resize(h);
size_t index = hash(k, h->vark ? strlen(k) : h->k_sz) % h->len;
int looped_once = 0;