Redis
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> Redis

Tập lệnh đã cố gắng tạo biến toàn cục

Xem mã nguồn trong tệp scripting.c

/* This function installs metamethods in the global table _G that prevent
 * the creation of globals accidentally.
 *
 * It should be the last to be called in the scripting engine initialization
 * sequence, because it may interact with creation of globals. */
void scriptingEnableGlobalsProtection(lua_State *lua) {
    char *s[32];
    sds code = sdsempty();
    int j = 0;

    /* strict.lua from: http://metalua.luaforge.net/src/lib/strict.lua.html.
     * Modified to be adapted to Redis. */
    s[j++]="local mt = {}\n";
    s[j++]="setmetatable(_G, mt)\n";
    s[j++]="mt.__newindex = function (t, n, v)\n";
    s[j++]="  if debug.getinfo(2) then\n";
    s[j++]="    local w = debug.getinfo(2, \"S\").what\n";
    s[j++]="    if w ~= \"main\" and w ~= \"C\" then\n";
    s[j++]="      error(\"Script attempted to create global variable '\"..tostring(n)..\"'\", 2)\n";
    s[j++]="    end\n";
    s[j++]="  end\n";
    s[j++]="  rawset(t, n, v)\n";
    s[j++]="end\n";
    s[j++]="mt.__index = function (t, n)\n";
    s[j++]="  if debug.getinfo(2) and debug.getinfo(2, \"S\").what ~= \"C\" then\n";
    s[j++]="    error(\"Script attempted to access unexisting global variable '\"..tostring(n)..\"'\", 2)\n";
    s[j++]="  end\n";
    s[j++]="  return rawget(t, n)\n";
    s[j++]="end\n";
    s[j++]=NULL;

    for (j = 0; s[j] != NULL; j++) code = sdscatlen(code,s[j],strlen(s[j]));
    luaL_loadbuffer(lua,code,sdslen(code),"@enable_strict_lua");
    lua_pcall(lua,0,0,0);
    sdsfree(code);
}

Chuỗi doc của scriptingEnableGlobalsProtection chỉ ra rằng mục đích là để thông báo cho các tác giả tập lệnh về lỗi phổ biến (không sử dụng local ).

Có vẻ như đây không phải là tính năng bảo mật, vì vậy chúng tôi có hai giải pháp:

Người ta có thể loại bỏ lớp bảo vệ này:

local mt = setmetatable(_G, nil)
-- define global functions / variables
function alex() return 3.1415 end
-- return globals protection mechanizm
setmetatable(_G, mt)

Hoặc sử dụng rawset :

local function alex() return 3.1415 end
rawset(_G, "alex", alex)



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Cách lưu trữ mảng băm trong redis

  2. Làm khô một RedisTemplate chung trong Mùa xuân 4

  3. Lắng nghe các thay đổi trong danh sách redis

  4. Redis keyspace thông báo hết hạn không kích hoạt

  5. Sao lưu AOF và RDB trong redis