From 042380a5243410b631c14144805e2462b430f47f Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 7 Apr 2017 11:01:53 +0100 Subject: [PATCH] [Feature] Add escaped version of lua_ucl import --- contrib/libucl/lua_ucl.c | 59 ++++++++++++++++++++++++++++++++-------- contrib/libucl/lua_ucl.h | 8 ++++++ 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/contrib/libucl/lua_ucl.c b/contrib/libucl/lua_ucl.c index 62b0652f5..2f7df686a 100644 --- a/contrib/libucl/lua_ucl.c +++ b/contrib/libucl/lua_ucl.c @@ -73,8 +73,8 @@ func = "huh"; static int ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj); static int ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, bool allow_array); -static ucl_object_t* ucl_object_lua_fromtable (lua_State *L, int idx); -static ucl_object_t* ucl_object_lua_fromelt (lua_State *L, int idx); +static ucl_object_t* ucl_object_lua_fromtable (lua_State *L, int idx, ucl_string_flags_t flags); +static ucl_object_t* ucl_object_lua_fromelt (lua_State *L, int idx, ucl_string_flags_t flags); static void *ucl_null; @@ -289,7 +289,7 @@ ucl_object_push_lua (lua_State *L, const ucl_object_t *obj, bool allow_array) * @param idx */ static ucl_object_t * -ucl_object_lua_fromtable (lua_State *L, int idx) +ucl_object_lua_fromtable (lua_State *L, int idx, ucl_string_flags_t flags) { ucl_object_t *obj, *top = NULL; size_t keylen; @@ -335,7 +335,7 @@ ucl_object_lua_fromtable (lua_State *L, int idx) for (i = 1; i <= max; i ++) { lua_pushinteger (L, i); lua_gettable (L, idx); - obj = ucl_object_lua_fromelt (L, lua_gettop (L)); + obj = ucl_object_lua_fromelt (L, lua_gettop (L), flags); if (obj != NULL) { ucl_array_append (top, obj); } @@ -348,7 +348,7 @@ ucl_object_lua_fromtable (lua_State *L, int idx) while (lua_next (L, idx) != 0) { /* copy key to avoid modifications */ k = lua_tolstring (L, -2, &keylen); - obj = ucl_object_lua_fromelt (L, lua_gettop (L)); + obj = ucl_object_lua_fromelt (L, lua_gettop (L), flags); if (obj != NULL) { ucl_object_insert_key (top, obj, k, keylen, true); @@ -367,18 +367,27 @@ ucl_object_lua_fromtable (lua_State *L, int idx) * @param idx */ static ucl_object_t * -ucl_object_lua_fromelt (lua_State *L, int idx) +ucl_object_lua_fromelt (lua_State *L, int idx, ucl_string_flags_t flags) { int type; double num; ucl_object_t *obj = NULL; struct ucl_lua_funcdata *fd; + const char *str; + size_t sz; type = lua_type (L, idx); switch (type) { case LUA_TSTRING: - obj = ucl_object_fromstring_common (lua_tostring (L, idx), 0, 0); + str = lua_tolstring (L, idx, &sz); + + if (str) { + obj = ucl_object_fromstring_common (str, sz, flags); + } + else { + obj = ucl_object_typed_new (UCL_NULL); + } break; case LUA_TNUMBER: num = lua_tonumber (L, idx); @@ -406,13 +415,13 @@ ucl_object_lua_fromelt (lua_State *L, int idx) lua_insert (L, 1); /* func, gen, obj */ lua_insert (L, 2); /* func, obj, gen */ lua_call(L, 2, 1); - obj = ucl_object_lua_fromelt (L, 1); + obj = ucl_object_lua_fromelt (L, 1, flags); } lua_pop (L, 2); } else { if (type == LUA_TTABLE) { - obj = ucl_object_lua_fromtable (L, idx); + obj = ucl_object_lua_fromtable (L, idx, flags); } else if (type == LUA_TFUNCTION) { fd = malloc (sizeof (*fd)); @@ -451,10 +460,38 @@ ucl_object_lua_import (lua_State *L, int idx) t = lua_type (L, idx); switch (t) { case LUA_TTABLE: - obj = ucl_object_lua_fromtable (L, idx); + obj = ucl_object_lua_fromtable (L, idx, 0); + break; + default: + obj = ucl_object_lua_fromelt (L, idx, 0); + break; + } + + return obj; +} + +/** + * @function ucl_object_lua_import_escape(L, idx) + * Extracts ucl object from lua variable at `idx` position escaping JSON strings + * @see ucl_object_push_lua for conversion definitions + * @param {lua_state} L lua state machine pointer + * @param {int} idx index where the source variable is placed + * @return {ucl_object_t} new ucl object extracted from lua variable. Reference count of this object is 1, + * this object thus needs to be unref'ed after usage. + */ +ucl_object_t * +ucl_object_lua_import_escape (lua_State *L, int idx) +{ + ucl_object_t *obj; + int t; + + t = lua_type (L, idx); + switch (t) { + case LUA_TTABLE: + obj = ucl_object_lua_fromtable (L, idx, UCL_STRING_ESCAPE); break; default: - obj = ucl_object_lua_fromelt (L, idx); + obj = ucl_object_lua_fromelt (L, idx, UCL_STRING_ESCAPE); break; } diff --git a/contrib/libucl/lua_ucl.h b/contrib/libucl/lua_ucl.h index 38e74d3f6..da7e014b9 100644 --- a/contrib/libucl/lua_ucl.h +++ b/contrib/libucl/lua_ucl.h @@ -54,6 +54,14 @@ UCL_EXTERN int luaopen_ucl (lua_State *L); */ UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx); +/** + * Import UCL object from lua state, escaping JSON strings + * @param L lua state + * @param idx index of object at the lua stack to convert to UCL + * @return new UCL object or NULL, the caller should unref object after using + */ +UCL_EXTERN ucl_object_t* ucl_object_lua_import_escape (lua_State *L, int idx); + /** * Push an object to lua * @param L lua state -- 2.39.5