diff options
| author | William Wilgus <me.theuser@yahoo.com> | 2018-01-29 08:13:37 +0100 |
|---|---|---|
| committer | William Wilgus <me.theuser@yahoo.com> | 2018-05-27 17:55:10 +0200 |
| commit | 0d41e13cf404ed8c75f78367eb0cd5153942a67f (patch) | |
| tree | 4599169e547a8390050dff5012b1b03f4c8dc4f3 /apps/plugins/lua | |
| parent | 1f63604e2ce522f531ae717b9f587cd58791b85f (diff) | |
| download | rockbox-0d41e13cf404ed8c75f78367eb0cd5153942a67f.zip rockbox-0d41e13cf404ed8c75f78367eb0cd5153942a67f.tar.gz rockbox-0d41e13cf404ed8c75f78367eb0cd5153942a67f.tar.bz2 rockbox-0d41e13cf404ed8c75f78367eb0cd5153942a67f.tar.xz | |
Fix lua lseek command / io lib
lua would not return or set arbitrary file positions
file:seek("set", 0) worked file:seek("cur") worked
but setting an offset or file:seek("end") failed
I tracked this down to a bug checking the return of rb->lseek
on error lseek returns a negative number and returns the file
position otherwise, the function was checking for if(N) instead of
if(N < 0)
Fixed - limited size of lseek to size of signed LuaNumber
Fixed - io:lines() stopped after first line containing only a newline
instead of returning a blank line and continuing till EOF
this fixes file:read("*l") as well
Fixed - ssize_t for read() with error checking
Change-Id: Ie859b288fb8f6814f1b3ae30992ecf78f2669de7
Diffstat (limited to 'apps/plugins/lua')
| -rw-r--r-- | apps/plugins/lua/liolib.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/apps/plugins/lua/liolib.c b/apps/plugins/lua/liolib.c index 7a43915..63377f9 100644 --- a/apps/plugins/lua/liolib.c +++ b/apps/plugins/lua/liolib.c @@ -18,7 +18,7 @@ #include "lualib.h" #include "rocklibc.h" - +#include "llimits.h" #define IO_INPUT 1 #define IO_OUTPUT 2 @@ -256,9 +256,9 @@ static int read_number (lua_State *L, int *f) { static int test_eof (lua_State *L, int *f) { - ssize_t s = rb->lseek(*f, 0, SEEK_CUR); + off_t s = rb->lseek(*f, 0, SEEK_CUR); lua_pushlstring(L, NULL, 0); - return s != rb->filesize(*f); + return s < rb->filesize(*f); } @@ -268,10 +268,11 @@ static int _read_line (lua_State *L, int *f) { luaL_buffinit(L, &b); for (;;) { size_t l; - size_t r; + off_t r; char *p = luaL_prepbuffer(&b); r = rb->read_line(*f, p, LUAL_BUFFERSIZE); l = strlen(p); + if (l == 0 || p[l-1] != '\n') luaL_addsize(&b, l); else { @@ -281,7 +282,7 @@ static int _read_line (lua_State *L, int *f) { } if (r < LUAL_BUFFERSIZE) { /* eof? */ luaL_pushresult(&b); /* close buffer */ - return (lua_objlen(L, -1) > 0); /* check whether read something */ + return (r > 0); /* check whether read something */ } } } @@ -289,7 +290,7 @@ static int _read_line (lua_State *L, int *f) { static int read_chars (lua_State *L, int *f, size_t n) { size_t rlen; /* how much to read */ - size_t nr; /* number of chars actually read */ + ssize_t nr; /* number of chars actually read */ luaL_Buffer b; luaL_buffinit(L, &b); rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ @@ -297,9 +298,11 @@ static int read_chars (lua_State *L, int *f, size_t n) { char *p = luaL_prepbuffer(&b); if (rlen > n) rlen = n; /* cannot read more than asked */ nr = rb->read(*f, p, rlen); + if (nr < 0) + luaL_error(L, "error reading file"); luaL_addsize(&b, nr); n -= nr; /* still have to read `n' chars */ - } while (n > 0 && nr == rlen); /* until end of count or eof */ + } while (n > 0 && nr == (ssize_t) rlen); /* until end of count or eof */ luaL_pushresult(&b); /* close buffer */ return (n == 0 || lua_objlen(L, -1) > 0); } @@ -414,11 +417,11 @@ static int f_seek (lua_State *L) { int f = *tofile(L); int op = luaL_checkoption(L, 2, "cur", modenames); long offset = luaL_optlong(L, 3, 0); - op = rb->lseek(f, offset, mode[op]); - if (op) + off_t size = rb->lseek(f, offset, mode[op]); + if (size < 0 || size > MAX_INT) /* signed limit */ return pushresult(L, 0, NULL); /* error */ else { - lua_pushinteger(L, rb->lseek(f, 0, SEEK_CUR)); + lua_pushinteger(L, (LUA_INTEGER) size ); return 1; } } @@ -465,4 +468,4 @@ LUALIB_API int luaopen_io (lua_State *L) { /* create (and set) default files */ lua_pop(L, 1); /* pop environment for default files */ return 1; -} +}
\ No newline at end of file |