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 | |
parent | 1f63604e2ce522f531ae717b9f587cd58791b85f (diff) | |
download | rockbox-0d41e13cf404ed8c75f78367eb0cd5153942a67f.tar.gz rockbox-0d41e13cf404ed8c75f78367eb0cd5153942a67f.zip |
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')
-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 7a43915f20..63377f94bd 100644 --- a/apps/plugins/lua/liolib.c +++ b/apps/plugins/lua/liolib.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include "lualib.h" | 18 | #include "lualib.h" |
19 | #include "rocklibc.h" | 19 | #include "rocklibc.h" |
20 | 20 | ||
21 | 21 | #include "llimits.h" | |
22 | 22 | ||
23 | #define IO_INPUT 1 | 23 | #define IO_INPUT 1 |
24 | #define IO_OUTPUT 2 | 24 | #define IO_OUTPUT 2 |
@@ -256,9 +256,9 @@ static int read_number (lua_State *L, int *f) { | |||
256 | 256 | ||
257 | 257 | ||
258 | static int test_eof (lua_State *L, int *f) { | 258 | static int test_eof (lua_State *L, int *f) { |
259 | ssize_t s = rb->lseek(*f, 0, SEEK_CUR); | 259 | off_t s = rb->lseek(*f, 0, SEEK_CUR); |
260 | lua_pushlstring(L, NULL, 0); | 260 | lua_pushlstring(L, NULL, 0); |
261 | return s != rb->filesize(*f); | 261 | return s < rb->filesize(*f); |
262 | } | 262 | } |
263 | 263 | ||
264 | 264 | ||
@@ -268,10 +268,11 @@ static int _read_line (lua_State *L, int *f) { | |||
268 | luaL_buffinit(L, &b); | 268 | luaL_buffinit(L, &b); |
269 | for (;;) { | 269 | for (;;) { |
270 | size_t l; | 270 | size_t l; |
271 | size_t r; | 271 | off_t r; |
272 | char *p = luaL_prepbuffer(&b); | 272 | char *p = luaL_prepbuffer(&b); |
273 | r = rb->read_line(*f, p, LUAL_BUFFERSIZE); | 273 | r = rb->read_line(*f, p, LUAL_BUFFERSIZE); |
274 | l = strlen(p); | 274 | l = strlen(p); |
275 | |||
275 | if (l == 0 || p[l-1] != '\n') | 276 | if (l == 0 || p[l-1] != '\n') |
276 | luaL_addsize(&b, l); | 277 | luaL_addsize(&b, l); |
277 | else { | 278 | else { |
@@ -281,7 +282,7 @@ static int _read_line (lua_State *L, int *f) { | |||
281 | } | 282 | } |
282 | if (r < LUAL_BUFFERSIZE) { /* eof? */ | 283 | if (r < LUAL_BUFFERSIZE) { /* eof? */ |
283 | luaL_pushresult(&b); /* close buffer */ | 284 | luaL_pushresult(&b); /* close buffer */ |
284 | return (lua_objlen(L, -1) > 0); /* check whether read something */ | 285 | return (r > 0); /* check whether read something */ |
285 | } | 286 | } |
286 | } | 287 | } |
287 | } | 288 | } |
@@ -289,7 +290,7 @@ static int _read_line (lua_State *L, int *f) { | |||
289 | 290 | ||
290 | static int read_chars (lua_State *L, int *f, size_t n) { | 291 | static int read_chars (lua_State *L, int *f, size_t n) { |
291 | size_t rlen; /* how much to read */ | 292 | size_t rlen; /* how much to read */ |
292 | size_t nr; /* number of chars actually read */ | 293 | ssize_t nr; /* number of chars actually read */ |
293 | luaL_Buffer b; | 294 | luaL_Buffer b; |
294 | luaL_buffinit(L, &b); | 295 | luaL_buffinit(L, &b); |
295 | rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ | 296 | 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) { | |||
297 | char *p = luaL_prepbuffer(&b); | 298 | char *p = luaL_prepbuffer(&b); |
298 | if (rlen > n) rlen = n; /* cannot read more than asked */ | 299 | if (rlen > n) rlen = n; /* cannot read more than asked */ |
299 | nr = rb->read(*f, p, rlen); | 300 | nr = rb->read(*f, p, rlen); |
301 | if (nr < 0) | ||
302 | luaL_error(L, "error reading file"); | ||
300 | luaL_addsize(&b, nr); | 303 | luaL_addsize(&b, nr); |
301 | n -= nr; /* still have to read `n' chars */ | 304 | n -= nr; /* still have to read `n' chars */ |
302 | } while (n > 0 && nr == rlen); /* until end of count or eof */ | 305 | } while (n > 0 && nr == (ssize_t) rlen); /* until end of count or eof */ |
303 | luaL_pushresult(&b); /* close buffer */ | 306 | luaL_pushresult(&b); /* close buffer */ |
304 | return (n == 0 || lua_objlen(L, -1) > 0); | 307 | return (n == 0 || lua_objlen(L, -1) > 0); |
305 | } | 308 | } |
@@ -414,11 +417,11 @@ static int f_seek (lua_State *L) { | |||
414 | int f = *tofile(L); | 417 | int f = *tofile(L); |
415 | int op = luaL_checkoption(L, 2, "cur", modenames); | 418 | int op = luaL_checkoption(L, 2, "cur", modenames); |
416 | long offset = luaL_optlong(L, 3, 0); | 419 | long offset = luaL_optlong(L, 3, 0); |
417 | op = rb->lseek(f, offset, mode[op]); | 420 | off_t size = rb->lseek(f, offset, mode[op]); |
418 | if (op) | 421 | if (size < 0 || size > MAX_INT) /* signed limit */ |
419 | return pushresult(L, 0, NULL); /* error */ | 422 | return pushresult(L, 0, NULL); /* error */ |
420 | else { | 423 | else { |
421 | lua_pushinteger(L, rb->lseek(f, 0, SEEK_CUR)); | 424 | lua_pushinteger(L, (LUA_INTEGER) size ); |
422 | return 1; | 425 | return 1; |
423 | } | 426 | } |
424 | } | 427 | } |
@@ -465,4 +468,4 @@ LUALIB_API int luaopen_io (lua_State *L) { | |||
465 | /* create (and set) default files */ | 468 | /* create (and set) default files */ |
466 | lua_pop(L, 1); /* pop environment for default files */ | 469 | lua_pop(L, 1); /* pop environment for default files */ |
467 | return 1; | 470 | return 1; |
468 | } | 471 | } \ No newline at end of file |