mirror of
https://github.com/lua/lua.git
synced 2025-01-14 05:43:00 +08:00
Buffer in 'luai_makeseed' measured in bytes
In the (rare) cases when sizeof(void*) or sizeof(time_t) are not multiples of sizeof(int), we still can use all their bytes in the seed.
This commit is contained in:
parent
1028f296a8
commit
25cd3d377e
25
lauxlib.c
25
lauxlib.c
@ -1124,29 +1124,30 @@ static void warnfon (void *ud, const char *message, int tocont) {
|
||||
#include <time.h>
|
||||
|
||||
|
||||
/*
|
||||
** Size of 'e' measured in number of 'unsigned int's. (In the weird
|
||||
** case that the division truncates, we just lose some part of the
|
||||
** value, no big deal.)
|
||||
*/
|
||||
#define sof(e) (sizeof(e) / sizeof(unsigned int))
|
||||
/* Size for the buffer, in bytes */
|
||||
#define BUFSEEDB (sizeof(void*) + sizeof(time_t))
|
||||
|
||||
/* Size for the buffer in int's, rounded up */
|
||||
#define BUFSEED ((BUFSEEDB + sizeof(int) - 1) / sizeof(int))
|
||||
|
||||
|
||||
#define addbuff(b,v) \
|
||||
(memcpy(b, &(v), sof(v) * sizeof(unsigned int)), b += sof(v))
|
||||
#define addbuff(b,v) (memcpy(b, &(v), sizeof(v)), b += sizeof(v))
|
||||
|
||||
|
||||
static unsigned int luai_makeseed (void) {
|
||||
unsigned int buff[sof(void*) + sof(time_t)];
|
||||
unsigned int buff[BUFSEED];
|
||||
unsigned int res;
|
||||
unsigned int *b = buff;
|
||||
unsigned int i;
|
||||
time_t t = time(NULL);
|
||||
void *h = buff;
|
||||
char *b = (char*)buff;
|
||||
addbuff(b, h); /* local variable's address */
|
||||
addbuff(b, t); /* time */
|
||||
/* fill (rare but possible) remain of the buffer with zeros */
|
||||
memset(b, 0, BUFSEED * sizeof(int) - BUFSEEDB);
|
||||
res = buff[0];
|
||||
for (b = buff + 1; b < buff + sof(buff); b++)
|
||||
res ^= (res >> 3) + (res << 7) + *b;
|
||||
for (i = 0; i < BUFSEED; i++)
|
||||
res ^= (res >> 3) + (res << 7) + buff[i];
|
||||
return res;
|
||||
}
|
||||
|
||||
|
7
ltests.c
7
ltests.c
@ -1160,6 +1160,12 @@ static int num2int (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static int makeseed (lua_State *L) {
|
||||
lua_pushinteger(L, luaL_makeseed(L));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int newstate (lua_State *L) {
|
||||
void *ud;
|
||||
lua_Alloc f = lua_getallocf(L, &ud);
|
||||
@ -1962,6 +1968,7 @@ static const struct luaL_Reg tests_funcs[] = {
|
||||
{"newstate", newstate},
|
||||
{"newuserdata", newuserdata},
|
||||
{"num2int", num2int},
|
||||
{"makeseed", makeseed},
|
||||
{"pushuserdata", pushuserdata},
|
||||
{"querystr", string_query},
|
||||
{"querytab", table_query},
|
||||
|
Loading…
x
Reference in New Issue
Block a user