diff options
| -rw-r--r-- | lstate.c | 37 | ||||
| -rw-r--r-- | lstate.h | 3 | ||||
| -rw-r--r-- | lstring.c | 13 | ||||
| -rw-r--r-- | lstring.h | 4 | ||||
| -rw-r--r-- | ltable.c | 4 |
5 files changed, 49 insertions, 12 deletions
| @@ -1,11 +1,12 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.91 2011/08/23 17:24:34 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.92 2011/10/03 17:54:25 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | #include <stddef.h> | 8 | #include <stddef.h> |
| 9 | #include <string.h> | ||
| 9 | 10 | ||
| 10 | #define lstate_c | 11 | #define lstate_c |
| 11 | #define LUA_CORE | 12 | #define LUA_CORE |
| @@ -42,6 +43,17 @@ | |||
| 42 | 43 | ||
| 43 | 44 | ||
| 44 | /* | 45 | /* |
| 46 | ** a macro to help the creation of a unique random seed when a state is | ||
| 47 | ** created; the seed is used to randomize hashes. | ||
| 48 | */ | ||
| 49 | #if !defined(luai_makeseed) | ||
| 50 | #include <time.h> | ||
| 51 | #define luai_makeseed(L) cast(size_t, time(NULL)) | ||
| 52 | #endif | ||
| 53 | |||
| 54 | |||
| 55 | |||
| 56 | /* | ||
| 45 | ** thread state + extra space | 57 | ** thread state + extra space |
| 46 | */ | 58 | */ |
| 47 | typedef struct LX { | 59 | typedef struct LX { |
| @@ -66,6 +78,28 @@ typedef struct LG { | |||
| 66 | 78 | ||
| 67 | 79 | ||
| 68 | /* | 80 | /* |
| 81 | ** Compute an initial seed as random as possible. In ANSI, rely on | ||
| 82 | ** Address Space Layour Randomization (if present) to increase | ||
| 83 | ** randomness.. | ||
| 84 | */ | ||
| 85 | #define addbuff(b,p,e) \ | ||
| 86 | { size_t t = cast(size_t, e); \ | ||
| 87 | memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } | ||
| 88 | |||
| 89 | static unsigned int makeseed (lua_State *L) { | ||
| 90 | char buff[4 * sizeof(size_t)]; | ||
| 91 | unsigned int h = luai_makeseed(); | ||
| 92 | int p = 0; | ||
| 93 | addbuff(buff, p, L); /* heap variable */ | ||
| 94 | addbuff(buff, p, &h); /* local variable */ | ||
| 95 | addbuff(buff, p, luaO_nilobject); /* global variable */ | ||
| 96 | addbuff(buff, p, &lua_newstate); /* public function */ | ||
| 97 | lua_assert(p == sizeof(buff)); | ||
| 98 | return luaS_hash(buff, p, h); | ||
| 99 | } | ||
| 100 | |||
| 101 | |||
| 102 | /* | ||
| 69 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) | 103 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) |
| 70 | ** invariant | 104 | ** invariant |
| 71 | */ | 105 | */ |
| @@ -242,6 +276,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
| 242 | g->frealloc = f; | 276 | g->frealloc = f; |
| 243 | g->ud = ud; | 277 | g->ud = ud; |
| 244 | g->mainthread = L; | 278 | g->mainthread = L; |
| 279 | g->seed = makeseed(L); | ||
| 245 | g->uvhead.u.l.prev = &g->uvhead; | 280 | g->uvhead.u.l.prev = &g->uvhead; |
| 246 | g->uvhead.u.l.next = &g->uvhead; | 281 | g->uvhead.u.l.next = &g->uvhead; |
| 247 | g->gcrunning = 0; /* no GC while building state */ | 282 | g->gcrunning = 0; /* no GC while building state */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.75 2012/01/20 22:05:50 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.76 2012/01/25 21:05:40 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -116,6 +116,7 @@ typedef struct global_State { | |||
| 116 | lu_mem lastmajormem; /* memory in use after last major collection */ | 116 | lu_mem lastmajormem; /* memory in use after last major collection */ |
| 117 | stringtable strt; /* hash table for strings */ | 117 | stringtable strt; /* hash table for strings */ |
| 118 | TValue l_registry; | 118 | TValue l_registry; |
| 119 | unsigned int seed; /* randomized seed for hashes */ | ||
| 119 | lu_byte currentwhite; | 120 | lu_byte currentwhite; |
| 120 | lu_byte gcstate; /* state of garbage collector */ | 121 | lu_byte gcstate; /* state of garbage collector */ |
| 121 | lu_byte gckind; /* kind of GC running */ | 122 | lu_byte gckind; /* kind of GC running */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 2.19 2011/05/03 16:01:57 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 2.21 2012/01/25 21:05:40 roberto Exp roberto $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -37,8 +37,8 @@ int luaS_eqstr (TString *a, TString *b) { | |||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | unsigned int luaS_hash (const char *str, size_t l) { | 40 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { |
| 41 | unsigned int h = cast(unsigned int, l); /* seed */ | 41 | unsigned int h = seed ^ l; |
| 42 | size_t l1; | 42 | size_t l1; |
| 43 | for (l1 = 0; l1 < l; l1++) | 43 | for (l1 = 0; l1 < l; l1++) |
| 44 | h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1])); | 44 | h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1])); |
| @@ -120,8 +120,9 @@ static TString *newshrstr (lua_State *L, const char *str, size_t l, | |||
| 120 | */ | 120 | */ |
| 121 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { | 121 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { |
| 122 | GCObject *o; | 122 | GCObject *o; |
| 123 | unsigned int h = luaS_hash(str, l); | 123 | global_State *g = G(L); |
| 124 | for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; | 124 | unsigned int h = luaS_hash(str, l, g->seed); |
| 125 | for (o = g->strt.hash[lmod(h, g->strt.size)]; | ||
| 125 | o != NULL; | 126 | o != NULL; |
| 126 | o = gch(o)->next) { | 127 | o = gch(o)->next) { |
| 127 | TString *ts = rawgco2ts(o); | 128 | TString *ts = rawgco2ts(o); |
| @@ -146,7 +147,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
| 146 | else { | 147 | else { |
| 147 | if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) | 148 | if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) |
| 148 | luaM_toobig(L); | 149 | luaM_toobig(L); |
| 149 | return createstrobj(L, str, l, LUA_TLNGSTR, 0, NULL); | 150 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); |
| 150 | } | 151 | } |
| 151 | } | 152 | } |
| 152 | 153 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.h,v 1.46 2010/04/05 16:26:37 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.48 2012/01/25 21:05:40 roberto Exp roberto $ |
| 3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -34,7 +34,7 @@ | |||
| 34 | #define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) | 34 | #define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) |
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l); | 37 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); |
| 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); | 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); |
| 39 | LUAI_FUNC int luaS_eqstr (TString *a, TString *b); | 39 | LUAI_FUNC int luaS_eqstr (TString *a, TString *b); |
| 40 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); | 40 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.67 2011/11/30 12:41:45 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.69 2012/01/25 21:05:40 roberto Exp roberto $ |
| 3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -101,7 +101,7 @@ static Node *mainposition (const Table *t, const TValue *key) { | |||
| 101 | case LUA_TLNGSTR: { | 101 | case LUA_TLNGSTR: { |
| 102 | TString *s = rawtsvalue(key); | 102 | TString *s = rawtsvalue(key); |
| 103 | if (s->tsv.extra == 0) { /* no hash? */ | 103 | if (s->tsv.extra == 0) { /* no hash? */ |
| 104 | s->tsv.hash = luaS_hash(getstr(s), s->tsv.len); | 104 | s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash); |
| 105 | s->tsv.extra = 1; /* now it has its hash */ | 105 | s->tsv.extra = 1; /* now it has its hash */ |
| 106 | } | 106 | } |
| 107 | return hashstr(t, rawtsvalue(key)); | 107 | return hashstr(t, rawtsvalue(key)); |
