From 3d0a7f3cd81daaa7d49de95de7fe4eb8d1288876 Mon Sep 17 00:00:00 2001 From: Adam Chlipala Date: Sat, 25 Apr 2009 14:35:49 -0400 Subject: Only allow single-file upload per control --- include/types.h | 5 ----- include/urweb.h | 7 +++---- lib/ur/basis.urs | 6 +----- src/c/driver.c | 9 ++------- src/c/urweb.c | 42 +++++++++++++++++------------------------- src/cjr_print.sml | 6 +++--- src/marshalcheck.sml | 2 +- tests/blob.ur | 13 +++---------- 8 files changed, 30 insertions(+), 60 deletions(-) diff --git a/include/types.h b/include/types.h index 0cb81cb5..69407b07 100644 --- a/include/types.h +++ b/include/types.h @@ -33,11 +33,6 @@ typedef struct uw_Basis_file { uw_Basis_blob data; } uw_Basis_file; -typedef struct uw_Basis_files { - size_t size; - uw_Basis_file *files; -} uw_Basis_files; - typedef enum { SUCCESS, FATAL, BOUNDED_RETRY, UNLIMITED_RETRY } failure_kind; diff --git a/include/urweb.h b/include/urweb.h index 4244aa6d..46eaab5f 100644 --- a/include/urweb.h +++ b/include/urweb.h @@ -43,8 +43,8 @@ void uw_set_input(uw_context, const char *name, char *value); char *uw_get_input(uw_context, int name); char *uw_get_optional_input(uw_context, int name); -void uw_set_file_input(uw_context, char *name, uw_Basis_files fs); -uw_Basis_files uw_get_file_input(uw_context, int name); +void uw_set_file_input(uw_context, char *name, uw_Basis_file); +uw_Basis_file uw_get_file_input(uw_context, int name); void uw_write(uw_context, const char*); @@ -164,5 +164,4 @@ uw_Basis_string uw_Basis_sigString(uw_context, uw_unit); uw_Basis_string uw_Basis_fileName(uw_context, uw_Basis_file); uw_Basis_blob uw_Basis_fileData(uw_context, uw_Basis_file); -uw_Basis_int uw_Basis_numFiles(uw_context, uw_Basis_files); -uw_Basis_file uw_Basis_fileNum(uw_context, uw_Basis_files, uw_Basis_int); + diff --git a/lib/ur/basis.urs b/lib/ur/basis.urs index ce969a37..bae58674 100644 --- a/lib/ur/basis.urs +++ b/lib/ur/basis.urs @@ -518,11 +518,7 @@ type file val fileName : file -> option string val fileData : file -> blob -type files -val numFiles : files -> int -val fileNum : files -> int -> file - -val upload : formTag files [] [Value = string, Size = int] +val upload : formTag file [] [Value = string, Size = int] con radio = [Body, Radio] val radio : formTag string radio [] diff --git a/src/c/driver.c b/src/c/driver.c index fa4f474b..6e06f32b 100644 --- a/src/c/driver.c +++ b/src/c/driver.c @@ -393,14 +393,9 @@ static void *worker(void *data) { part += boundary_len; if (filename) { - uw_Basis_file *f = malloc(sizeof(uw_Basis_file)); - uw_Basis_files fs = { 1, f }; + uw_Basis_file f = {filename, {part_len, after_sub_headers}}; - f->name = filename; - f->data.size = part_len; - f->data.data = after_sub_headers; - - uw_set_file_input(ctx, name, fs); + uw_set_file_input(ctx, name, f); } else uw_set_input(ctx, name, after_sub_headers); } diff --git a/src/c/urweb.c b/src/c/urweb.c index 99564605..a73371ef 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -283,14 +283,14 @@ typedef struct { } delta; typedef enum { - UNSET, NORMAL, FILES + UNSET, NORMAL, FIL } input_kind; typedef struct { input_kind kind; union { char *normal; - uw_Basis_files files; + uw_Basis_file file; } data; } input; @@ -580,8 +580,8 @@ char *uw_get_input(uw_context ctx, int n) { switch (ctx->inputs[n].kind) { case UNSET: return NULL; - case FILES: - uw_error(ctx, FATAL, "Tried to read a files form input as normal"); + case FIL: + uw_error(ctx, FATAL, "Tried to read a file form input as normal"); case NORMAL: return ctx->inputs[n].data.normal; default: @@ -598,8 +598,8 @@ char *uw_get_optional_input(uw_context ctx, int n) { switch (ctx->inputs[n].kind) { case UNSET: return ""; - case FILES: - uw_error(ctx, FATAL, "Tried to read a files form input as normal"); + case FIL: + uw_error(ctx, FATAL, "Tried to read a file form input as normal"); case NORMAL: return ctx->inputs[n].data.normal; default: @@ -607,7 +607,7 @@ char *uw_get_optional_input(uw_context ctx, int n) { } } -void uw_set_file_input(uw_context ctx, const char *name, uw_Basis_files fs) { +void uw_set_file_input(uw_context ctx, const char *name, uw_Basis_file f) { int n = uw_input_num(name); if (n < 0) @@ -616,11 +616,13 @@ void uw_set_file_input(uw_context ctx, const char *name, uw_Basis_files fs) { if (n >= uw_inputs_len) uw_error(ctx, FATAL, "For file input name %s, index %d is out of range", name, n); - ctx->inputs[n].kind = FILES; - ctx->inputs[n].data.files = fs; + ctx->inputs[n].kind = FIL; + ctx->inputs[n].data.file = f; } -uw_Basis_files uw_get_file_input(uw_context ctx, int n) { +void *uw_malloc(uw_context ctx, size_t len); + +uw_Basis_file uw_get_file_input(uw_context ctx, int n) { if (n < 0) uw_error(ctx, FATAL, "Negative file input index %d", n); if (n >= uw_inputs_len) @@ -629,11 +631,12 @@ uw_Basis_files uw_get_file_input(uw_context ctx, int n) { switch (ctx->inputs[n].kind) { case UNSET: { - uw_Basis_files fs = {}; - return fs; + char *data = uw_malloc(ctx, 0); + uw_Basis_file f = {"", {0, data}}; + return f; } - case FILES: - return ctx->inputs[n].data.files; + case FIL: + return ctx->inputs[n].data.file; case NORMAL: uw_error(ctx, FATAL, "Tried to read a normal form input as files"); default: @@ -2128,14 +2131,3 @@ uw_Basis_string uw_Basis_fileName(uw_context ctx, uw_Basis_file f) { uw_Basis_blob uw_Basis_fileData(uw_context ctx, uw_Basis_file f) { return f.data; } - -uw_Basis_int uw_Basis_numFiles(uw_context ctx, uw_Basis_files fs) { - return fs.size; -} - -uw_Basis_file uw_Basis_fileNum(uw_context ctx, uw_Basis_files fs, uw_Basis_int n) { - if (n < 0 || n >= fs.size) - uw_error(ctx, FATAL, "Files index out of bounds"); - else - return fs.files[n]; -} diff --git a/src/cjr_print.sml b/src/cjr_print.sml index d24cbfa4..07e3931f 100644 --- a/src/cjr_print.sml +++ b/src/cjr_print.sml @@ -456,9 +456,9 @@ fun isBlob Blob = true | isBlob (Nullable t) = isBlob t | isBlob _ = false -fun isFiles (t : typ) = +fun isFile (t : typ) = case #1 t of - TFfi ("Basis", "files") => true + TFfi ("Basis", "file") => true | _ => false fun p_sql_type' t = @@ -2423,7 +2423,7 @@ fun p_file env (ds, ps) = (TFfi ("Basis", "bool"), _) => "optional_" | _ => "" in - if isFiles t then + if isFile t then box [string "uw_input_", p_ident x, space, diff --git a/src/marshalcheck.sml b/src/marshalcheck.sml index 3d517779..e39bf7c5 100644 --- a/src/marshalcheck.sml +++ b/src/marshalcheck.sml @@ -57,7 +57,7 @@ val clientToServer = [("Basis", "int"), ("Basis", "float"), ("Basis", "string"), ("Basis", "time"), - ("Basis", "files"), + ("Basis", "file"), ("Basis", "unit"), ("Basis", "option"), ("Basis", "bool")] diff --git a/tests/blob.ur b/tests/blob.ur index a62eefc1..37c3f753 100644 --- a/tests/blob.ur +++ b/tests/blob.ur @@ -2,16 +2,9 @@ sequence s table t : { Id : int, Nam : option string, Data : blob, Desc : string } fun save r = - if numFiles r.Data <> 1 then - error Please submit exactly one file. - else - let - val f = fileNum r.Data 0 - in - id <- nextval s; - dml (INSERT INTO t (Id, Nam, Data, Desc) VALUES ({[id]}, {[fileName f]}, {[fileData f]}, {[r.Desc]})); - main () - end + id <- nextval s; + dml (INSERT INTO t (Id, Nam, Data, Desc) VALUES ({[id]}, {[fileName r.Data]}, {[fileData r.Data]}, {[r.Desc]})); + main () and main () = return
-- cgit v1.2.3