diff --git a/HISTORY.md b/HISTORY.md index e498068ae..9d39efafe 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +v0.3.1 (2014-6-16) +----------- +* Bugfix: lua mongo driver . Hold reply string before decode bson data. +* More check in bson decoding. +* Use big-endian for encoding bson objectid. + v0.3.0 (2014-6-2) ----------- * Add cluster support diff --git a/Makefile b/Makefile index 9c84351d4..3c5fd4465 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ $(CSERVICE_PATH) : define CSERVICE_TEMP $$(CSERVICE_PATH)/$(1).so : service-src/service_$(1).c | $$(CSERVICE_PATH) - $(CC) $$(CFLAGS) $$(SHARED) $$< -o $$@ -Iskynet-src + $$(CC) $$(CFLAGS) $$(SHARED) $$< -o $$@ -Iskynet-src endef $(foreach v, $(CSERVICE), $(eval $(call CSERVICE_TEMP,$(v)))) diff --git a/lualib-src/lua-bson.c b/lualib-src/lua-bson.c index ca73bae03..07fb77e29 100644 --- a/lualib-src/lua-bson.c +++ b/lualib-src/lua-bson.c @@ -68,6 +68,13 @@ struct bson_reader { int size; }; +static inline int32_t +get_length(const uint8_t * data) { + const uint8_t * b = (const uint8_t *)data; + int32_t len = b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24; + return len; +} + static inline void bson_destroy(struct bson *b) { if (b->ptr != b->buffer) { @@ -644,7 +651,7 @@ static int lmakeindex(lua_State *L) { int32_t *bson = luaL_checkudata(L,1,"bson"); const uint8_t * start = (const uint8_t *)bson; - struct bson_reader br = { start+4, *bson - 5 }; + struct bson_reader br = { start+4, get_length(start) - 5 }; lua_newtable(L); for (;;) { @@ -820,7 +827,9 @@ ldecode(lua_State *L) { if (data == NULL) { return 0; } - struct bson_reader br = { (const uint8_t *)data , *data }; + const uint8_t * b = (const uint8_t *)data; + int32_t len = get_length(b); + struct bson_reader br = { b , len }; unpack_dict(L, &br, false); @@ -1140,14 +1149,14 @@ lobjectid(lua_State *L) { } } else { time_t ti = time(NULL); - oid[2] = ti & 0xff; - oid[3] = (ti>>8) & 0xff; - oid[4] = (ti>>16) & 0xff; - oid[5] = (ti>>24) & 0xff; + oid[2] = (ti>>24) & 0xff; + oid[3] = (ti>>16) & 0xff; + oid[4] = (ti>>8) & 0xff; + oid[5] = ti & 0xff; memcpy(oid+6 , oid_header, 5); - oid[11] = oid_counter & 0xff; + oid[11] = (oid_counter>>16) & 0xff; oid[12] = (oid_counter>>8) & 0xff; - oid[13] = (oid_counter>>16) & 0xff; + oid[13] = oid_counter & 0xff; ++oid_counter; } lua_pushlstring( L, (const char *)oid, 14); diff --git a/lualib-src/lua-mongo.c b/lualib-src/lua-mongo.c index a0d312fd5..3e4666dc6 100644 --- a/lualib-src/lua-mongo.c +++ b/lualib-src/lua-mongo.c @@ -260,6 +260,13 @@ op_reply(lua_State *L) { lua_pushnil(L); lua_rawseti(L, 2, i); } + } else { + if (sz >= 4) { + sz -= get_length((document)doc); + } + } + if (sz != 0) { + return luaL_error(L, "Invalid result bson document"); } lua_pushboolean(L,1); lua_pushinteger(L, id); diff --git a/lualib/mongo.lua b/lualib/mongo.lua index 7b1c6f69f..f9eece357 100644 --- a/lualib/mongo.lua +++ b/lualib/mongo.lua @@ -98,7 +98,7 @@ function mongo.client( conf ) host = obj.host, port = obj.port, response = dispatch_reply, - auth = mongo_auth(conf), + auth = mongo_auth(obj), } setmetatable(obj, client_meta) obj.__sock:connect(true) -- try connect only once @@ -167,7 +167,9 @@ function mongo_db:runCommand(cmd,cmd_v,...) bson_cmd = bson_encode_order(cmd,cmd_v,...) end local pack = driver.query(request_id, 0, self.__cmd, 0, 1, bson_cmd) - local doc = sock:request(pack, request_id).document + -- we must hold req (req.data), because req.document is a lightuserdata, it's a pointer to the string (req.data) + local req = sock:request(pack, request_id) + local doc = req.document return bson_decode(doc) end @@ -224,7 +226,9 @@ function mongo_collection:findOne(query, selector) local request_id = conn:genId() local sock = conn.__sock local pack = driver.query(request_id, 0, self.full_name, 0, 1, query and bson_encode(query) or empty_bson, selector and bson_encode(selector)) - local doc = sock:request(pack, request_id).document + -- we must hold req (req.data), because req.document is a lightuserdata, it's a pointer to the string (req.data) + local req = sock:request(pack, request_id) + local doc = req.document return bson_decode(doc) end