From b130ca554f13e17c787a1c6fd09e67dd7727a4d3 Mon Sep 17 00:00:00 2001 From: Daniel Dickinson Date: Tue, 15 Dec 2015 11:37:33 -0500 Subject: lib-nixio / luci-base: Fix for reading csrf token prevents file upload The call to http.formvalue in order to read the csrf token causes _parse_input to be triggered *before* controllers and cbi maps have been built. This results in the failure of file uploads because the file handler is not yet in place when _parse_input gets called, and it is in _parse_input that POST data is parsed (including files). To fix this we add the ability to write file fields to temporary files (using mkstemp and unlink in nixio.file) and use this to store file data until the filehandler is registered, with a fallback to reading the file data into memory. Once the filehandler callback gets registered we iterate though all previously parsed (saved) files and copy the data to the file handler, and then close the temporary file (which finally removes because we unlinked after creating the file, but didn't close the file so unlink was deferred). Signed-off-by: Daniel Dickinson --- libs/luci-lib-nixio/src/file.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'libs') diff --git a/libs/luci-lib-nixio/src/file.c b/libs/luci-lib-nixio/src/file.c index b86e040e1..cfa35dfd1 100644 --- a/libs/luci-lib-nixio/src/file.c +++ b/libs/luci-lib-nixio/src/file.c @@ -79,6 +79,38 @@ static int nixio_open(lua_State *L) { return 1; } +static int nixio_mkstemp(lua_State *L) { + const char *intemplate = luaL_checklstring(L, 1, NULL); + size_t len = lua_strlen(L, 1); + char *template = (char *)lua_newuserdata(L, 13 + len); + if (!template) { + return luaL_error(L, "out of memory"); + } + snprintf(template, 13 + len, "/tmp/%s.XXXXXX", intemplate); + + int fd; + + do { + fd = mkstemp(template); + } while (fd == -1 && errno == EINTR); + if (fd == -1) { + return nixio__perror(L); + } + unlink(template); + + int *udata = lua_newuserdata(L, sizeof(int)); + if (!udata) { + return luaL_error(L, "out of memory"); + } + + *udata = fd; + + luaL_getmetatable(L, NIXIO_FILE_META); + lua_setmetatable(L, -2); + + return 1; +} + static int nixio_open_flags(lua_State *L) { int mode = 0; const int j = lua_gettop(L); @@ -366,6 +398,7 @@ static const luaL_reg R[] = { {"dup", nixio_dup}, {"open", nixio_open}, {"open_flags", nixio_open_flags}, + {"mkstemp", nixio_mkstemp}, {"pipe", nixio_pipe}, {NULL, NULL} }; -- cgit v1.2.3