webmcp

changeset 402:04172238d79b

Do not require "engine" field to be set for mondelefant.connect{...}; Fixed bugs in mondelefant.connect{...} that could have crashed Lua; Shortened Lua registry key for mondelefant library
author jbe
date Wed Jan 06 02:39:50 2016 +0100 (2016-01-06)
parents ad437022be90
children 0cb4bf644f1b
files libraries/mondelefant/mondelefant_native.c
line diff
     1.1 --- a/libraries/mondelefant/mondelefant_native.c	Mon Jan 04 00:48:47 2016 +0100
     1.2 +++ b/libraries/mondelefant/mondelefant_native.c	Wed Jan 06 02:39:50 2016 +0100
     1.3 @@ -9,7 +9,7 @@
     1.4  // NOTE: Comments with format "// <number>" denote the Lua stack position
     1.5  
     1.6  // prefix for all Lua registry entries of this library:
     1.7 -#define MONDELEFANT_REGKEY "e449ba8d9a53d353_mondelefant_"
     1.8 +#define MONDELEFANT_REGKEY "mondelefant_"
     1.9  
    1.10  // registry key of module "mondelefant_native":
    1.11  #define MONDELEFANT_MODULE_REGKEY (MONDELEFANT_REGKEY "module")
    1.12 @@ -194,76 +194,63 @@
    1.13  // "connect" function of library, which establishes a database connection
    1.14  // and returns a database connection handle:
    1.15  static int mondelefant_connect(lua_State *L) {
    1.16 -  luaL_Buffer buf;  // Lua string buffer to create 'conninfo' (see below)
    1.17    const char *conninfo;  // string for PQconnectdb function
    1.18    PGconn *pgconn;  // PGconn object as returned by PQconnectdb function
    1.19    mondelefant_conn_t *conn;  // C-structure for userdata
    1.20 -  // expect a table as first argument:
    1.21 -  luaL_checktype(L, 1, LUA_TTABLE);
    1.22 -  // if engine is anything but "postgresql", then raise error:
    1.23 -  lua_settop(L, 1);
    1.24 -  lua_getfield(L, 1, "engine");  // 2
    1.25 -  if (!lua_toboolean(L, 2)) {
    1.26 -    return luaL_argerror(L, 1, "no database engine selected");
    1.27 -  }
    1.28 -  lua_pushliteral(L, "postgresql");  // 3
    1.29 -  if (!lua_rawequal(L, 2, 3)) {
    1.30 -    return luaL_argerror(L, 1,
    1.31 -      "only database engine 'postgresql' is supported"
    1.32 -    );
    1.33 -  }
    1.34 -  // copy conninfo string for PQconnectdb function from argument table to
    1.35 -  // stack position 2:
    1.36 -  lua_settop(L, 1);
    1.37 -  lua_getfield(L, 1, "conninfo");  // 2
    1.38 -  // if no conninfo string was found, then assemble one from the named
    1.39 -  // options except "engine" option:
    1.40 -  if (!lua_toboolean(L, 2)) {
    1.41 +  // check if string is given as first argument:
    1.42 +  if (lua_type(L, 1) != LUA_TSTRING) {
    1.43 +    // expect a table as first argument if no string is given:
    1.44 +    luaL_checktype(L, 1, LUA_TTABLE);
    1.45 +    // copy conninfo string for PQconnectdb function from argument table to
    1.46 +    // stack position 2:
    1.47      lua_settop(L, 1);
    1.48 -    lua_pushnil(L);  // slot for key at stack position 2
    1.49 -    lua_pushnil(L);  // slot for value at stack position 3
    1.50 -    luaL_buffinit(L, &buf);
    1.51 -    {
    1.52 +    lua_getfield(L, 1, "conninfo");  // 2
    1.53 +    // check if conninfo is set:
    1.54 +    if (!lua_isnil(L, 2)) {
    1.55 +      // if yes, use that value but check its type:
    1.56 +      luaL_argcheck(L, lua_type(L, 2) == LUA_TSTRING, 2, "\"conninfo\" value is not a string");
    1.57 +    } else {
    1.58 +      // otherwise assemble conninfo string from the named options:
    1.59 +      luaL_Buffer buf;
    1.60        int need_seperator = 0;
    1.61 +      const char *value;
    1.62 +      size_t value_len;
    1.63 +      size_t value_pos = 0;
    1.64 +      lua_settop(L, 1);
    1.65 +      lua_pushnil(L);  // slot for key at stack position 2
    1.66 +      lua_pushnil(L);  // slot for value at stack position 3
    1.67 +      luaL_buffinit(L, &buf);
    1.68        while (lua_pushvalue(L, 2), lua_next(L, 1)) {
    1.69 +        luaL_argcheck(L, lua_isstring(L, -2), 1, "key in table is not a string");
    1.70 +        luaL_argcheck(L, lua_isstring(L, -1), 1, "value in table is not a string");
    1.71 +        value = lua_tolstring(L, -1, &value_len);
    1.72          lua_replace(L, 3);
    1.73 +        lua_pop(L, 1);
    1.74          lua_replace(L, 2);
    1.75 +        if (need_seperator) luaL_addchar(&buf, ' ');
    1.76          // NOTE: numbers will be converted to strings automatically here,
    1.77          // but perhaps this will change in future versions of lua
    1.78 -        luaL_argcheck(L,
    1.79 -          lua_isstring(L, 2) && lua_isstring(L, 3), 1, "key is not a string"
    1.80 -        );
    1.81          lua_pushvalue(L, 2);
    1.82 -        lua_pushliteral(L, "engine");
    1.83 -        if (!lua_rawequal(L, -2, -1)) {
    1.84 -          const char *value;
    1.85 -          size_t value_len;
    1.86 -          size_t value_pos = 0;
    1.87 -          lua_pop(L, 1);
    1.88 -          if (need_seperator) luaL_addchar(&buf, ' ');
    1.89 -          luaL_addvalue(&buf);
    1.90 -          luaL_addchar(&buf, '=');
    1.91 -          luaL_addchar(&buf, '\'');
    1.92 -          value = lua_tolstring(L, 3, &value_len);
    1.93 -          do {
    1.94 -            char c;
    1.95 -            c = value[value_pos++];
    1.96 -            if (c == '\'') luaL_addchar(&buf, '\\');
    1.97 -            luaL_addchar(&buf, c);
    1.98 -          } while (value_pos < value_len);
    1.99 -          luaL_addchar(&buf, '\'');
   1.100 -          need_seperator = 1;
   1.101 -        } else {
   1.102 -          lua_pop(L, 1);
   1.103 -        }
   1.104 +        luaL_addvalue(&buf);
   1.105 +        luaL_addchar(&buf, '=');
   1.106 +        luaL_addchar(&buf, '\'');
   1.107 +        do {
   1.108 +          char c;
   1.109 +          c = value[value_pos++];
   1.110 +          if (c == '\'') luaL_addchar(&buf, '\\');
   1.111 +          luaL_addchar(&buf, c);
   1.112 +        } while (value_pos < value_len);
   1.113 +        luaL_addchar(&buf, '\'');
   1.114 +        need_seperator = 1;
   1.115        }
   1.116 +      luaL_pushresult(&buf);
   1.117      }
   1.118 -    luaL_pushresult(&buf);
   1.119 -    lua_replace(L, 2);
   1.120 -    lua_settop(L, 2);
   1.121 +    // ensure that string is on stack position 1 which is the top of stack:
   1.122 +    lua_replace(L, 1);
   1.123 +    lua_settop(L, 1);
   1.124    }
   1.125 -  // use conninfo string on stack position 2:
   1.126 -  conninfo = lua_tostring(L, 2);
   1.127 +  // use conninfo string on stack position 1:
   1.128 +  conninfo = lua_tostring(L, 1);
   1.129    // call PQconnectdb function of libpq:
   1.130    pgconn = PQconnectdb(conninfo);
   1.131    // throw or return errors, if neccessary:
   1.132 @@ -273,18 +260,18 @@
   1.133      );
   1.134    }
   1.135    if (PQstatus(pgconn) != CONNECTION_OK) {
   1.136 -    lua_pushnil(L);  // 3
   1.137 -    mondelefant_push_first_line(L, PQerrorMessage(pgconn));  // 4
   1.138 -    lua_newtable(L);  // 5
   1.139 +    lua_pushnil(L);  // 2
   1.140 +    mondelefant_push_first_line(L, PQerrorMessage(pgconn));  // 3
   1.141 +    lua_newtable(L);  // 4
   1.142      lua_getfield(L,
   1.143        LUA_REGISTRYINDEX,
   1.144        MONDELEFANT_ERROROBJECT_MT_REGKEY
   1.145      );
   1.146 -    lua_setmetatable(L, 5);
   1.147 +    lua_setmetatable(L, 4);
   1.148      lua_pushliteral(L, MONDELEFANT_ERRCODE_CONNECTION);
   1.149 -    lua_setfield(L, 5, "code");
   1.150 -    lua_pushvalue(L, 4);
   1.151 -    lua_setfield(L, 5, "message");
   1.152 +    lua_setfield(L, 4, "code");
   1.153 +    lua_pushvalue(L, 3);
   1.154 +    lua_setfield(L, 4, "message");
   1.155      PQfinish(pgconn);
   1.156      return 3;
   1.157    }

Impressum / About Us