Skip to content

Commit 7486e53

Browse files
committed
avoid circular reference while encodeing bson
1 parent 9aaa35e commit 7486e53

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

lualib-src/lua-bson.c

+18-13
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#define DEFAULT_CAP 64
1414
#define MAX_NUMBER 1024
15+
// avoid circular reference while encodeing
16+
#define MAX_DEPTH 128
1517

1618
#define BSON_REAL 1
1719
#define BSON_STRING 2
@@ -236,7 +238,7 @@ write_double(struct bson *b, lua_Number d) {
236238
}
237239
}
238240

239-
static void pack_dict(lua_State *L, struct bson *b, bool array);
241+
static void pack_dict(lua_State *L, struct bson *b, bool array, int depth);
240242

241243
static inline void
242244
append_key(struct bson *bs, int type, const char *key, size_t sz) {
@@ -268,7 +270,7 @@ append_number(struct bson *bs, lua_State *L, const char *key, size_t sz) {
268270
}
269271

270272
static void
271-
append_table(struct bson *bs, lua_State *L, const char *key, size_t sz) {
273+
append_table(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth) {
272274
size_t len = lua_rawlen(L, -1);
273275
bool isarray = false;
274276
if (len > 0) {
@@ -284,7 +286,7 @@ append_table(struct bson *bs, lua_State *L, const char *key, size_t sz) {
284286
} else {
285287
append_key(bs, BSON_DOCUMENT, key, sz);
286288
}
287-
pack_dict(L, bs, isarray);
289+
pack_dict(L, bs, isarray, depth);
288290
}
289291

290292
static void
@@ -297,7 +299,7 @@ write_binary(struct bson *b, const void * buffer, size_t sz) {
297299
}
298300

299301
static void
300-
append_one(struct bson *bs, lua_State *L, const char *key, size_t sz) {
302+
append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth) {
301303
int vt = lua_type(L,-1);
302304
switch(vt) {
303305
case LUA_TNUMBER:
@@ -385,7 +387,7 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz) {
385387
break;
386388
}
387389
case LUA_TTABLE:
388-
append_table(bs, L, key, sz);
390+
append_table(bs, L, key, sz, depth+1);
389391
break;
390392
case LUA_TBOOLEAN:
391393
append_key(bs, BSON_BOOLEAN, key, sz);
@@ -407,7 +409,10 @@ bson_numstr( char *str, unsigned int i ) {
407409
}
408410

409411
static void
410-
pack_dict(lua_State *L, struct bson *b, bool isarray) {
412+
pack_dict(lua_State *L, struct bson *b, bool isarray, int depth) {
413+
if (depth > MAX_DEPTH) {
414+
luaL_error(L, "Too depth while encoding bson");
415+
}
411416
luaL_checkstack(L, 16, NULL); // reserve enough stack space to pack table
412417
int length = reserve_length(b);
413418
lua_pushnil(L);
@@ -424,7 +429,7 @@ pack_dict(lua_State *L, struct bson *b, bool isarray) {
424429
sz = bson_numstr(numberkey, (unsigned int)lua_tointeger(L,-2)-1);
425430
key = numberkey;
426431

427-
append_one(b, L, key, sz);
432+
append_one(b, L, key, sz, depth);
428433
lua_pop(L,1);
429434
} else {
430435
switch(kt) {
@@ -433,12 +438,12 @@ pack_dict(lua_State *L, struct bson *b, bool isarray) {
433438
lua_pushvalue(L,-2);
434439
lua_insert(L,-2);
435440
key = lua_tolstring(L,-2,&sz);
436-
append_one(b, L, key, sz);
441+
append_one(b, L, key, sz, depth);
437442
lua_pop(L,2);
438443
break;
439444
case LUA_TSTRING:
440445
key = lua_tolstring(L,-2,&sz);
441-
append_one(b, L, key, sz);
446+
append_one(b, L, key, sz, depth);
442447
lua_pop(L,1);
443448
break;
444449
default:
@@ -452,7 +457,7 @@ pack_dict(lua_State *L, struct bson *b, bool isarray) {
452457
}
453458

454459
static void
455-
pack_ordered_dict(lua_State *L, struct bson *b, int n) {
460+
pack_ordered_dict(lua_State *L, struct bson *b, int n, int depth) {
456461
int length = reserve_length(b);
457462
int i;
458463
for (i=0;i<n;i+=2) {
@@ -462,7 +467,7 @@ pack_ordered_dict(lua_State *L, struct bson *b, int n) {
462467
luaL_error(L, "Argument %d need a string", i+1);
463468
}
464469
lua_pushvalue(L, i+2);
465-
append_one(b, L, key, sz);
470+
append_one(b, L, key, sz, depth);
466471
lua_pop(L,1);
467472
}
468473
write_byte(b,0);
@@ -848,7 +853,7 @@ lencode(lua_State *L) {
848853
bson_create(&b);
849854
lua_settop(L,1);
850855
luaL_checktype(L, 1, LUA_TTABLE);
851-
pack_dict(L, &b, false);
856+
pack_dict(L, &b, false, 0);
852857
void * ud = lua_newuserdata(L, b.size);
853858
memcpy(ud, b.ptr, b.size);
854859
bson_destroy(&b);
@@ -864,7 +869,7 @@ lencode_order(lua_State *L) {
864869
if (n%2 != 0) {
865870
return luaL_error(L, "Invalid ordered dict");
866871
}
867-
pack_ordered_dict(L, &b, n);
872+
pack_ordered_dict(L, &b, n, 0);
868873
lua_settop(L,1);
869874
void * ud = lua_newuserdata(L, b.size);
870875
memcpy(ud, b.ptr, b.size);

0 commit comments

Comments
 (0)