lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Although Lua is very convenient for configuration files/data it is
often dangerously overpowered, if you're not a trusting kind of person
;)

The data mode patch defines a new mode 'd' for loadfile which raises
an error at the lexical stage if any loop construct or function
definition has been found when loading the file.  It's useful to have
if-statements, but for/while/repeat/goto/function are no go!

E.g consider the file:

-- whack.lua
while true do
  print 'whack'
end

then dofile('whack.lua','d') will give the error "whack.lua:1: loop or
function in file"

The patch is against 5.2.3

>From e02d9f0e2496bb7948aa48f4b82250d55f607651 Mon Sep 17 00:00:00 2001
From: steve donovan <steve.j.donovan@gmail.com>
Date: Mon, 17 Mar 2014 17:32:31 +0200
Subject: [PATCH] data mode patch

---
 src/ldo.c     |    9 ++++++---
 src/llex.c    |    9 ++++++---
 src/llex.h    |    1 +
 src/lparser.c |    3 ++-
 src/lparser.h |    2 +-
 5 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/ldo.c b/src/ldo.c
index e9dd5fa..1d85eb4 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -638,7 +638,7 @@ static void checkmode (lua_State *L, const char
*mode, const char *x) {


 static void f_parser (lua_State *L, void *ud) {
-  int i;
+  int i, noloop = 0;
   Closure *cl;
   struct SParser *p = cast(struct SParser *, ud);
   int c = zgetc(p->z);  /* read first character */
@@ -647,8 +647,11 @@ static void f_parser (lua_State *L, void *ud) {
     cl = luaU_undump(L, p->z, &p->buff, p->name);
   }
   else {
-    checkmode(L, p->mode, "text");
-    cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
+    if (p->mode && p->mode[0] == 'd')
+      noloop = 1;
+    else
+      checkmode(L, p->mode, "text");
+    cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c, noloop);
   }
   lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
   for (i = 0; i < cl->l.nupvalues; i++) {  /* initialize upvalues */
diff --git a/src/llex.c b/src/llex.c
index c4b820e..3eae5f5 100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -494,9 +494,12 @@ static int llex (LexState *ls, SemInfo *seminfo) {
           ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
                                   luaZ_bufflen(ls->buff));
           seminfo->ts = ts;
-          if (isreserved(ts))  /* reserved word? */
-            return ts->tsv.extra - 1 + FIRST_RESERVED;
-          else {
+          if (isreserved(ts)) {  /* reserved word? */
+            int tok = ts->tsv.extra - 1 + FIRST_RESERVED;
+            if (ls->noloop && (tok==TK_FOR || tok==TK_WHILE ||
tok==TK_FUNCTION || tok==TK_REPEAT || tok==TK_GOTO))
+              lexerror(ls, "loop or function in file", 0);
+            return tok;
+          } else {
             return TK_NAME;
           }
         }
diff --git a/src/llex.h b/src/llex.h
index a4acdd3..26cd38b 100644
--- a/src/llex.h
+++ b/src/llex.h
@@ -61,6 +61,7 @@ typedef struct LexState {
   struct Dyndata *dyd;  /* dynamic structures used by the parser */
   TString *source;  /* current source name */
   TString *envn;  /* environment variable name */
+  int noloop;   /* safe data mode */
   char decpoint;  /* locale decimal point */
 } LexState;

diff --git a/src/lparser.c b/src/lparser.c
index 9e1a9ca..0d35ff0 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1616,7 +1616,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {


 Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
-                      Dyndata *dyd, const char *name, int firstchar) {
+                      Dyndata *dyd, const char *name, int firstchar,
int noloop) {
   LexState lexstate;
   FuncState funcstate;
   Closure *cl = luaF_newLclosure(L, 1);  /* create main closure */
@@ -1627,6 +1627,7 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
   funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */
   lexstate.buff = buff;
   lexstate.dyd = dyd;
+  lexstate.noloop = noloop;
   dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
   luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
   mainfunc(&lexstate, &funcstate);
diff --git a/src/lparser.h b/src/lparser.h
index 0346e3c..e69767e 100644
--- a/src/lparser.h
+++ b/src/lparser.h
@@ -113,7 +113,7 @@ typedef struct FuncState {


 LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
-                                Dyndata *dyd, const char *name, int firstchar);
+                                Dyndata *dyd, const char *name, int
firstchar, int noloop);


 #endif
-- 
1.7.4.msysgit.0