From 8980c630bf40e05dad71ded377e3d0f0a17b076c Mon Sep 17 00:00:00 2001
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 20 Dec 2010 15:25:36 -0200
Subject: error when indexing strings with invalid keys

---
 lstrlib.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

(limited to 'lstrlib.c')

diff --git a/lstrlib.c b/lstrlib.c
index 3acaf875..379fd20f 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lstrlib.c,v 1.159 2010/11/19 16:25:51 roberto Exp roberto $
+** $Id: lstrlib.c,v 1.160 2010/12/10 19:03:46 roberto Exp roberto $
 ** Standard library for string operations and pattern-matching
 ** See Copyright Notice in lua.h
 */
@@ -903,6 +903,15 @@ static int str_format (lua_State *L) {
 /* }====================================================== */
 
 
+static int noindex (lua_State *L) {
+  const char *f = lua_tostring(L, 2);
+  if (f)
+    return luaL_error(L, "no field '%s' in strings", f);
+  else
+    return luaL_error(L, "no such field in strings");
+}
+
+
 static const luaL_Reg strlib[] = {
   {"byte", str_byte},
   {"char", str_char},
@@ -918,19 +927,22 @@ static const luaL_Reg strlib[] = {
   {"reverse", str_reverse},
   {"sub", str_sub},
   {"upper", str_upper},
+  {"__index", noindex},
   {NULL, NULL}
 };
 
 
 static void createmetatable (lua_State *L) {
-  lua_createtable(L, 0, 1);  /* create metatable for strings */
+  /* setmetatable("", {__index = string}) */
   lua_pushliteral(L, "");  /* dummy string */
-  lua_pushvalue(L, -2);
-  lua_setmetatable(L, -2);  /* set string metatable */
+  lua_createtable(L, 0, 1);  /* create metatable for strings */
+  lua_pushvalue(L, -3);  /* set the string library... */
+  lua_setfield(L, -2, "__index");  /* ...as the __index metamethod */
+  lua_setmetatable(L, -2);  /* set metatable for strings */
   lua_pop(L, 1);  /* pop dummy string */
-  lua_pushvalue(L, -2);  /* string library... */
-  lua_setfield(L, -2, "__index");  /* ...is the __index metamethod */
-  lua_pop(L, 1);  /* pop metatable */
+  /* setmetatable(string, string) */
+  lua_pushvalue(L, -1);  /* push string library */
+  lua_setmetatable(L, -2);  /* set it as its own metatable */
 }
 
 
-- 
cgit v1.2.3-55-g6feb