crude input validation against a blacklist
[webgit] / src / query.c
index 2e9f29e4b9103bb910b946128c41d56d769dc4f8..e9c30e4d5191750dadf167943b0f75cd6c9ced16 100644 (file)
 
 
 #include "query.h"
+#include "repo.h"
 
 #include "cwa.h"
 
+#include <stdint.h>
+#include <time.h>
 
 void
 ctgit_query_init (struct ctgit_query* q)
 {
+  q->request = NULL;
+  q->now = time (NULL);
+
   q->repo = NULL;
-  q->action = cwa_strdup ("main");
+  q->action = NULL;
   q->object = NULL;
   q->head = NULL;
   llist_init (&q->repos);
@@ -46,87 +52,103 @@ ctgit_query_destroy (struct ctgit_query* q)
   free (q->head);
 
   LLIST_WHILE_HEAD (&q->repos, head)
-    {
-      struct ctgit_repo_info* h = (struct ctgit_repo_info*)head;
-
-      free (h->path);
-      free (h->name);
-
-      free (h->owner);
-      free (h->description);
-      free (h->pull_url);
-
-      llist_unlink (head);
-      free (h);
-    }
+    ctgit_repoinfo_free ((struct ctgit_repo_info*) head);
 
   return q;
 }
 
 
 void
-ctgit_query_add_repo (struct ctgit_query* q, char* path)
+ctgit_query_add_repo (struct ctgit_query* q, const char* path)
 {
-  if (!path)
+  struct ctgit_repo_info* ri = ctgit_repoinfo_new (q, path);
+  if (!ri)
     return;
 
-  struct ctgit_repo_info* self = cwa_malloc (sizeof(struct ctgit_repo_info));
+  LList p = &q->repos;
+  LLIST_FOREACH (&q->repos, node)
+    {
+      struct ctgit_repo_info* n = (struct ctgit_repo_info*)node;
+      if (strcmp (n->name, ri->name) > 0)
+        break;
+      p = node;
+    }
+  llist_insert_next (p, &ri->node);
+}
 
-  llist_init (&self->node);
-  self->path = cwa_strdup (path);
+const int
+ctgit_validate_string (const char *s, size_t v_sz)
+{
+  for (const char* c = ";$&|<>!`#"; *c; ++c)
+    if (memchr (s, *c, v_sz))
+      return 0;
 
-  self->owner = NULL;
-  self->description = NULL;
-  self->pull_url = NULL;
+  return 1;
 }
 
-
 static void
 ctgit_repo_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
 {
+  (void) self;
   struct ctgit_query* q = (struct ctgit_query*) u_dat;
 
-  free (q->repo);
-  q->repo = strdup(v);
-
-  fprintf (stderr,"repo='%s'\n", v);
+  /* TODO validate that v is a probably legal repo name (alnum()) */
+  if (ctgit_validate_string (v, v_sz))
+    {
+      free (q->repo);
+      q->repo = cwa_strndup (v, v_sz);
+    }
 }
 
+
 static void
 ctgit_action_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
 {
+  (void) self;
   struct ctgit_query* q = (struct ctgit_query*) u_dat;
 
-  free (q->action);
-  q->action = strdup(v);
-
-  fprintf (stderr,"action='%s'\n", v);
+  /* TODO validate that v is a probably legal action name alpha() */
+  if (ctgit_validate_string (v, v_sz))
+    {
+      free (q->action);
+      q->action = cwa_strndup (v, v_sz);
+    }
 }
 
+
 static void
 ctgit_object_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
 {
+  (void) self;
   struct ctgit_query* q = (struct ctgit_query*) u_dat;
 
-  free (q->object);
-  q->object = strdup (v);
+  if (!q->action)
+    q->action = cwa_strndup ("object", SIZE_MAX);
 
-  fprintf (stderr,"object='%s'\n", v);
+  /* TODO validate that v is a probably sha1 (<=40 chars, hex) */
+  if (ctgit_validate_string (v, v_sz))
+    {
+      free (q->object);
+      q->object = cwa_strndup (v, v_sz);
+    }
 }
 
+
 static void
 ctgit_ref_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
 {
+  (void) self;
   struct ctgit_query* q = (struct ctgit_query*) u_dat;
 
-  free (q->head);
-  q->head = strdup(v);
-
-  fprintf (stderr,"head='%s'\n", v);
+  /* TODO validate that v is a probably legal reference (alnum() || one of '_/.') */
+  if (ctgit_validate_string (v, v_sz))
+    {
+      free (q->head);
+      q->head = cwa_strndup (v, v_sz);
+    }
 }
 
 
-
 void
 ctgit_param_dispatch (const Cgi self,
                       const char* name,