From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Subject: [tarantool-patches] [PATCH 6/7] msgpack: allow to pass 'const char *' into decode() Date: Wed, 15 May 2019 02:06:24 +0300 [thread overview] Message-ID: <b264d32baedb1a8e2b8733e00e30c374eed4a81a.1557875116.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1557875116.git.v.shpilevoy@tarantool.org> msgpack.decode() internally uses 'const char *' variable to decode msgpack, but somewhy expects only 'char *' as input. This commit allows to pass 'const char *' as well. --- src/lua/msgpack.c | 16 +++++----------- src/lua/utils.c | 20 +++++++++++++++++++- src/lua/utils.h | 11 +++++++++++ test/app-tap/msgpack.test.lua | 7 ++++--- test/app/msgpack.result | 18 ++++++++++++++++++ test/app/msgpack.test.lua | 7 +++++++ 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/lua/msgpack.c b/src/lua/msgpack.c index 73bda80ea..66b83b894 100644 --- a/src/lua/msgpack.c +++ b/src/lua/msgpack.c @@ -50,8 +50,6 @@ luamp_error(void *error_ctx) luaL_error(L, diag_last_error(diag_get())->errmsg); } -static uint32_t CTID_CHAR_PTR; - struct luaL_serializer *luaL_msgpack_default = NULL; static enum mp_type @@ -332,9 +330,8 @@ lua_msgpack_encode(lua_State *L) static int lua_msgpack_decode_cdata(lua_State *L, bool check) { - uint32_t ctypeid; - const char *data = *(const char **)luaL_checkcdata(L, 1, &ctypeid); - if (ctypeid != CTID_CHAR_PTR) { + const char *data; + if (luaL_checkconstchar(L, 1, &data) != 0) { return luaL_error(L, "msgpack.decode: " "a Lua string or 'char *' expected"); } @@ -346,7 +343,7 @@ lua_msgpack_decode_cdata(lua_State *L, bool check) } struct luaL_serializer *cfg = luaL_checkserializer(L); luamp_decode(L, cfg, &data); - *(const char **)luaL_pushcdata(L, ctypeid) = data; + *(const char **)luaL_pushcdata(L, CTID_CHAR_PTR) = data; return 2; } @@ -435,9 +432,8 @@ verify_decode_header_args(lua_State *L, const char *func_name, return luaL_error(L, "Usage: %s(ptr, size)", func_name); /* Verify ptr type. */ - uint32_t ctypeid; - const char *data = *(char **) luaL_checkcdata(L, 1, &ctypeid); - if (ctypeid != CTID_CHAR_PTR) + const char *data; + if (luaL_checkconstchar(L, 1, &data) != 0) return luaL_error(L, "%s: 'char *' expected", func_name); /* Verify size type and value. */ @@ -525,8 +521,6 @@ lua_msgpack_new(lua_State *L) LUALIB_API int luaopen_msgpack(lua_State *L) { - CTID_CHAR_PTR = luaL_ctypeid(L, "char *"); - assert(CTID_CHAR_PTR != 0); luaL_msgpack_default = luaL_newserializer(L, "msgpack", msgpacklib); return 1; } diff --git a/src/lua/utils.c b/src/lua/utils.c index f53d7e588..01a0cd894 100644 --- a/src/lua/utils.c +++ b/src/lua/utils.c @@ -43,6 +43,8 @@ int luaL_array_metatable_ref = LUA_REFNIL; static uint32_t CTID_STRUCT_IBUF; static uint32_t CTID_STRUCT_IBUF_PTR; +uint32_t CTID_CHAR_PTR; +uint32_t CTID_CONST_CHAR_PTR; void * luaL_pushcdata(struct lua_State *L, uint32_t ctypeid) @@ -1076,6 +1078,19 @@ luaL_checkibuf(struct lua_State *L, int idx) return NULL; } +int +luaL_checkconstchar(struct lua_State *L, int idx, const char **res) +{ + if (lua_type(L, idx) != LUA_TCDATA) + return -1; + uint32_t cdata_type; + void *cdata = luaL_checkcdata(L, idx, &cdata_type); + if (cdata_type != CTID_CHAR_PTR && cdata_type != CTID_CONST_CHAR_PTR) + return -1; + *res = cdata != NULL ? *(const char **) cdata : NULL; + return 0; +} + lua_State * luaT_state(void) { @@ -1209,6 +1224,9 @@ tarantool_lua_utils_init(struct lua_State *L) assert(CTID_STRUCT_IBUF != 0); CTID_STRUCT_IBUF_PTR = luaL_ctypeid(L, "struct ibuf *"); assert(CTID_STRUCT_IBUF_PTR != 0); - + CTID_CHAR_PTR = luaL_ctypeid(L, "char *"); + assert(CTID_CHAR_PTR != 0); + CTID_CONST_CHAR_PTR = luaL_ctypeid(L, "const char *"); + assert(CTID_CONST_CHAR_PTR != 0); return 0; } diff --git a/src/lua/utils.h b/src/lua/utils.h index cf51eb132..3d887a5ce 100644 --- a/src/lua/utils.h +++ b/src/lua/utils.h @@ -67,6 +67,9 @@ struct ibuf; extern struct lua_State *tarantool_L; extern struct ibuf *tarantool_lua_ibuf; +extern uint32_t CTID_CONST_CHAR_PTR; +extern uint32_t CTID_CHAR_PTR; + /** \cond public */ /** @@ -544,6 +547,14 @@ luaL_checkfinite(struct lua_State *L, struct luaL_serializer *cfg, struct ibuf * luaL_checkibuf(struct lua_State *L, int idx); +/** + * Check if a value on @a L stack by index @a idx is pointer at + * char or const char. '(char *)NULL' is also considered a valid + * char pointer. + */ +int +luaL_checkconstchar(struct lua_State *L, int idx, const char **res); + /* {{{ Helper functions to interact with a Lua iterator from C */ /** diff --git a/test/app-tap/msgpack.test.lua b/test/app-tap/msgpack.test.lua index 1b0bb9806..bd095e5ae 100755 --- a/test/app-tap/msgpack.test.lua +++ b/test/app-tap/msgpack.test.lua @@ -57,6 +57,7 @@ local function test_decode_array_map_header(test, s) 'of buffer' local non_positive_size_err = 'msgpack.decode_[^_]+_header: ' .. 'non%-positive size' + local wrong_type_err = "msgpack.decode_[^_]+_header: 'char %*' expected" local decode_cases = { { @@ -175,17 +176,17 @@ local function test_decode_array_map_header(test, s) { 'data is nil', args = {nil, 1}, - exp_err = 'expected cdata as 1 argument', + exp_err = wrong_type_err, }, { 'data is not cdata', args = {1, 1}, - exp_err = 'expected cdata as 1 argument', + exp_err = wrong_type_err, }, { 'data with wrong cdata type', args = {box.tuple.new(), 1}, - exp_err = "msgpack.decode_[^_]+_header: 'char %*' expected", + exp_err = wrong_type_err, }, { 'size has wrong type', diff --git a/test/app/msgpack.result b/test/app/msgpack.result index 9fc42fc3c..105f503da 100644 --- a/test/app/msgpack.result +++ b/test/app/msgpack.result @@ -4,6 +4,9 @@ buffer = require 'buffer' msgpack = require 'msgpack' --- ... +ffi = require 'ffi' +--- +... -- Arguments check. buf = buffer.ibuf() --- @@ -226,3 +229,18 @@ size = msgpack.encode({c = 3, d = 4}, buf) --- - {'c': 3, 'd': 4} ... +-- Decode should accept both 'char *' and 'const char *'. +buf:reset() +--- +... +size = msgpack.encode(100, buf) +--- +... +(msgpack.decode(ffi.cast('char *', buf.rpos), size)) +--- +- 100 +... +(msgpack.decode(ffi.cast('const char *', buf.rpos), size)) +--- +- 100 +... diff --git a/test/app/msgpack.test.lua b/test/app/msgpack.test.lua index 0920fa507..de8fd4e37 100644 --- a/test/app/msgpack.test.lua +++ b/test/app/msgpack.test.lua @@ -1,5 +1,6 @@ buffer = require 'buffer' msgpack = require 'msgpack' +ffi = require 'ffi' -- Arguments check. buf = buffer.ibuf() @@ -71,3 +72,9 @@ size = msgpack.encode({a = 1, b = 2}, buf) buf = buffer.ibuf() size = msgpack.encode({c = 3, d = 4}, buf) (msgpack.decode(buf.rpos, size)) + +-- Decode should accept both 'char *' and 'const char *'. +buf:reset() +size = msgpack.encode(100, buf) +(msgpack.decode(ffi.cast('char *', buf.rpos), size)) +(msgpack.decode(ffi.cast('const char *', buf.rpos), size)) -- 2.20.1 (Apple Git-117)
next prev parent reply other threads:[~2019-05-14 23:06 UTC|newest] Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-05-14 23:06 [tarantool-patches] [PATCH 0/7] swim lua preparation, again Vladislav Shpilevoy 2019-05-14 23:06 ` [tarantool-patches] [PATCH 1/7] swim: drop swim_info() function Vladislav Shpilevoy 2019-05-15 2:00 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 2/7] swim: encapsulate 'uint16' payload size inside swim.c Vladislav Shpilevoy 2019-05-15 2:02 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 3/7] swim: do not rebind when new 'port' is 0 Vladislav Shpilevoy 2019-05-15 2:02 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 4/7] swim: set 'left' status in self on swim_quit() Vladislav Shpilevoy 2019-05-15 2:03 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 5/7] msgpack: allow to pass 'struct ibuf *' into encode() Vladislav Shpilevoy 2019-05-15 2:05 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` Vladislav Shpilevoy [this message] 2019-05-15 2:05 ` [tarantool-patches] Re: [PATCH 6/7] msgpack: allow to pass 'const char *' into decode() Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 7/7] Drop an unused function and class Vladislav Shpilevoy 2019-05-15 2:06 ` [tarantool-patches] " Konstantin Osipov 2019-05-15 10:02 ` [tarantool-patches] Re: [PATCH 0/7] swim lua preparation, again Vladislav Shpilevoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=b264d32baedb1a8e2b8733e00e30c374eed4a81a.1557875116.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH 6/7] msgpack: allow to pass '\''const char *'\'' into decode()' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox