gint cbref;
guint nargs;
gchar **args;
+ gsize *arglens;
struct rspamd_async_watcher *w;
struct lua_redis_userdata *c;
struct lua_redis_ctx *ctx;
}
static void
-lua_redis_free_args (char **args, guint nargs)
+lua_redis_free_args (char **args, gsize *arglens, guint nargs)
{
guint i;
if (args) {
for (i = 0; i < nargs; i ++) {
- g_free (args[i]);
+ g_slice_free1 (arglens[i], args[i]);
}
g_slice_free1 (sizeof (gchar *) * nargs, args);
+ g_slice_free1 (sizeof (gsize) * nargs, arglens);
}
}
}
LL_FOREACH_SAFE (ud->specific, cur, tmp) {
- lua_redis_free_args (cur->args, cur->nargs);
+ lua_redis_free_args (cur->args, cur->arglens, cur->nargs);
if (cur->cbref != -1) {
luaL_unref (ud->L, LUA_REGISTRYINDEX, cur->cbref);
static void
lua_redis_parse_args (lua_State *L, gint idx, const gchar *cmd,
- gchar ***pargs, guint *nargs)
+ gchar ***pargs, gsize **parglens, guint *nargs)
{
gchar **args = NULL;
+ gsize *arglens;
gint top;
if (idx != 0 && lua_type (L, idx) == LUA_TTABLE) {
if (lua_isstring (L, -1)) {
top ++;
}
+ else if (lua_type (L, -1) == LUA_TUSERDATA) {
+ top ++;
+ }
lua_pop (L, 1);
}
args = g_slice_alloc ((top + 1) * sizeof (gchar *));
+ arglens = g_slice_alloc ((top + 1) * sizeof (gsize));
lua_pushnil (L);
- args[0] = g_strdup (cmd);
+ arglens[0] = strlen (cmd);
+ args[0] = g_slice_alloc (arglens[0]);
+ memcpy (args[0], cmd, arglens[0]);
top = 1;
while (lua_next (L, -2) != 0) {
if (lua_isstring (L, -1)) {
- args[top++] = g_strdup (lua_tostring (L, -1));
+ const gchar *s;
+
+ s = lua_tolstring (L, -1, &arglens[top]);
+ args[top] = g_slice_alloc (arglens[top]);
+ memcpy (args[top], s, arglens[top]);
+ top ++;
+ }
+ else if (lua_type (L, -1) == LUA_TUSERDATA) {
+ struct rspamd_lua_text *t;
+
+ t = lua_check_text (L, -1);
+
+ if (t && t->start) {
+ arglens[top] = t->len;
+ args[top] = g_slice_alloc (arglens[top]);
+ memcpy (args[top], t->start, arglens[top]);
+ top ++;
+ }
}
+
lua_pop (L, 1);
}
}
else {
/* Use merely cmd */
+
args = g_slice_alloc (sizeof (gchar *));
- args[0] = g_strdup (cmd);
+ arglens = g_slice_alloc (sizeof (gsize));
+ lua_pushnil (L);
+ arglens[0] = strlen (cmd);
+ args[0] = g_slice_alloc (arglens[0]);
+ memcpy (args[0], cmd, arglens[0]);
top = 1;
}
*pargs = args;
+ *parglens = arglens;
*nargs = top;
}
lua_pushstring (L, "args");
lua_gettable (L, -2);
- lua_redis_parse_args (L, -1, cmd, &sp_ud->args, &sp_ud->nargs);
+ lua_redis_parse_args (L, -1, cmd, &sp_ud->args, &sp_ud->arglens,
+ &sp_ud->nargs);
lua_pop (L, 1);
LL_PREPEND (ud->specific, sp_ud);
cmd = luaL_checkstring (L, args_pos);
if (top > 4) {
lua_redis_parse_args (L, args_pos + 1, cmd, &sp_ud->args,
- &sp_ud->nargs);
+ &sp_ud->arglens, &sp_ud->nargs);
}
else {
- lua_redis_parse_args (L, 0, cmd, &sp_ud->args, &sp_ud->nargs);
+ lua_redis_parse_args (L, 0, cmd, &sp_ud->args,
+ &sp_ud->arglens, &sp_ud->nargs);
}
LL_PREPEND (ud->specific, sp_ud);
sp_ud,
sp_ud->nargs,
(const gchar **)sp_ud->args,
- NULL);
+ sp_ud->arglens);
if (ret == REDIS_OK) {
rspamd_session_add_event (ud->task->s,
gboolean ret = FALSE;
gdouble timeout = REDIS_DEFAULT_TIMEOUT;
gchar **args = NULL;
+ gsize *arglens = NULL;
guint nargs = 0;
redisContext *ctx;
redisReply *r;
lua_pushstring (L, "args");
lua_gettable (L, -2);
- lua_redis_parse_args (L, -1, cmd, &args, &nargs);
+ lua_redis_parse_args (L, -1, cmd, &args, &arglens, &nargs);
lua_pop (L, 1);
if (addr && cmd) {
if (ctx == NULL || ctx->err) {
redisFree (ctx);
- lua_redis_free_args (args, nargs);
+ lua_redis_free_args (args, arglens, nargs);
lua_pushboolean (L, FALSE);
return 1;
r = redisCommandArgv (ctx,
nargs,
(const gchar **)args,
- NULL);
+ arglens);
if (r != NULL) {
if (r->type != REDIS_REPLY_ERROR) {
lua_pushboolean (L, FALSE);
lua_pushstring (L, r->str);
}
+
freeReplyObject (r);
redisFree (ctx);
+ lua_redis_free_args (args, arglens, nargs);
return 2;
}
else {
msg_info ("call to redis failed: %s", ctx->errstr);
redisFree (ctx);
- lua_redis_free_args (args, nargs);
+ lua_redis_free_args (args, arglens, nargs);
lua_pushboolean (L, FALSE);
}
}
const gchar *cmd = NULL;
gint args_pos = 2;
gchar **args = NULL;
+ gsize *arglens = NULL;
guint nargs = 0;
gint cbref = -1, ret;
struct timeval tv;
sp_ud->ctx = ctx;
lua_redis_parse_args (L, args_pos, cmd, &sp_ud->args,
- &sp_ud->nargs);
+ &sp_ud->arglens, &sp_ud->nargs);
LL_PREPEND (sp_ud->c->specific, sp_ud);
sp_ud,
sp_ud->nargs,
(const gchar **)sp_ud->args,
- NULL);
+ sp_ud->arglens);
if (ret == REDIS_OK) {
rspamd_session_add_event (sp_ud->c->task->s,
sp_ud->c->ctx->errstr);
lua_pushboolean (L, 0);
lua_pushstring (L, sp_ud->c->ctx->errstr);
+
return 2;
}
}
}
if (ctx->d.sync) {
- lua_redis_parse_args (L, args_pos, cmd, &args, &nargs);
+ lua_redis_parse_args (L, args_pos, cmd, &args, &arglens, &nargs);
if (nargs > 0) {
- redisAppendCommandArgv (ctx->d.sync, nargs,
- (const char **)args, NULL);
- ctx->cmds_pending ++;
- lua_redis_free_args (args, nargs);
+ if (redisAppendCommandArgv (ctx->d.sync, nargs,
+ (const char **)args, arglens) == REDIS_OK) {
+ ctx->cmds_pending ++;
+ }
+
+ lua_redis_free_args (args, arglens, nargs);
}
else {
lua_pushstring (L, "cannot append commands when not connected");