From e57cccdefbbac1bef7b397d65df6a353bd9cfeee Mon Sep 17 00:00:00 2001
From: antirez <antirez@gmail.com>
Date: Mon, 16 Nov 2015 10:29:35 +0100
Subject: [PATCH] Lua debugger: use sds_malloc() to allocate eval cli array.

Redis-cli handles the debugger "eval" command in a special way since
sdssplitargs() would not be ok: we need to send the Redis debugger the
whole Lua script without any parsing. However in order to later free the
argument vector inside redis-cli using just sdsfreesplitres(), we need
to allocate the array of SDS pointers using the same allocator SDS is
using, that may differ to what Redis is using.

So now a newer version of SDS exports sds_malloc() and other allocator
functions to give access, to the program it is linked to, the allocator
used internally by SDS.
---
 deps/hiredis/sds.c | 9 +++++++++
 deps/hiredis/sds.h | 8 ++++++++
 src/redis-cli.c    | 2 +-
 src/sds.c          | 9 +++++++++
 src/sds.h          | 8 ++++++++
 5 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/deps/hiredis/sds.c b/deps/hiredis/sds.c
index f1e4f949d..e3dd67352 100644
--- a/deps/hiredis/sds.c
+++ b/deps/hiredis/sds.c
@@ -1088,6 +1088,15 @@ sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
     return join;
 }
 
+/* Wrappers to the allocators used by SDS. Note that SDS will actually
+ * just use the macros defined into sdsalloc.h in order to avoid to pay
+ * the overhead of function calls. Here we define these wrappers only for
+ * the programs SDS is linked to, if they want to touch the SDS internals
+ * even if they use a different allocator. */
+void *sds_malloc(size_t size) { return s_malloc(size); }
+void *sds_realloc(void *ptr, size_t size) { return s_realloc(ptr,size); }
+void sds_free(void *ptr) { s_free(ptr); }
+
 #if defined(SDS_TEST_MAIN)
 #include <stdio.h>
 #include "testhelp.h"
diff --git a/deps/hiredis/sds.h b/deps/hiredis/sds.h
index d7eb4c7d0..394f8b52e 100644
--- a/deps/hiredis/sds.h
+++ b/deps/hiredis/sds.h
@@ -258,6 +258,14 @@ sds sdsRemoveFreeSpace(sds s);
 size_t sdsAllocSize(sds s);
 void *sdsAllocPtr(sds s);
 
+/* Export the allocator used by SDS to the program using SDS.
+ * Sometimes the program SDS is linked to, may use a different set of
+ * allocators, but may want to allocate or free things that SDS will
+ * respectively free or allocate. */
+void *sds_malloc(size_t size);
+void *sds_realloc(void *ptr, size_t size);
+void sds_free(void *ptr);
+
 #ifdef REDIS_TEST
 int sdsTest(int argc, char *argv[]);
 #endif
diff --git a/src/redis-cli.c b/src/redis-cli.c
index f85463f2e..09fc28add 100644
--- a/src/redis-cli.c
+++ b/src/redis-cli.c
@@ -1050,7 +1050,7 @@ static sds *cliSplitArgs(char *line, int *argc) {
     if (config.eval_ldb && (strstr(line,"eval ") == line ||
                             strstr(line,"e ") == line))
     {
-        sds *argv = zmalloc(sizeof(sds)*2);
+        sds *argv = sds_malloc(sizeof(sds)*2);
         *argc = 2;
         int len = strlen(line);
         int elen = line[1] == ' ' ? 2 : 5; /* "e " or "eval "? */
diff --git a/src/sds.c b/src/sds.c
index f1e4f949d..e3dd67352 100644
--- a/src/sds.c
+++ b/src/sds.c
@@ -1088,6 +1088,15 @@ sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
     return join;
 }
 
+/* Wrappers to the allocators used by SDS. Note that SDS will actually
+ * just use the macros defined into sdsalloc.h in order to avoid to pay
+ * the overhead of function calls. Here we define these wrappers only for
+ * the programs SDS is linked to, if they want to touch the SDS internals
+ * even if they use a different allocator. */
+void *sds_malloc(size_t size) { return s_malloc(size); }
+void *sds_realloc(void *ptr, size_t size) { return s_realloc(ptr,size); }
+void sds_free(void *ptr) { s_free(ptr); }
+
 #if defined(SDS_TEST_MAIN)
 #include <stdio.h>
 #include "testhelp.h"
diff --git a/src/sds.h b/src/sds.h
index d7eb4c7d0..394f8b52e 100644
--- a/src/sds.h
+++ b/src/sds.h
@@ -258,6 +258,14 @@ sds sdsRemoveFreeSpace(sds s);
 size_t sdsAllocSize(sds s);
 void *sdsAllocPtr(sds s);
 
+/* Export the allocator used by SDS to the program using SDS.
+ * Sometimes the program SDS is linked to, may use a different set of
+ * allocators, but may want to allocate or free things that SDS will
+ * respectively free or allocate. */
+void *sds_malloc(size_t size);
+void *sds_realloc(void *ptr, size_t size);
+void sds_free(void *ptr);
+
 #ifdef REDIS_TEST
 int sdsTest(int argc, char *argv[]);
 #endif