From f0782a6e8633988a935097c195899773da2c2ad1 Mon Sep 17 00:00:00 2001
From: Matt Stancliff <matt@genges.com>
Date: Fri, 7 Mar 2014 16:32:04 -0500
Subject: [PATCH] Fix key extraction for z{union,inter}store

The previous implementation wasn't taking into account
the storage key in position 1 being a requirement (it
was only counting the source keys in positions 3 to N).

Fixes antirez/redis#1581
---
 src/db.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/db.c b/src/db.c
index 41e95b6b..5170c6ed 100644
--- a/src/db.c
+++ b/src/db.c
@@ -993,9 +993,23 @@ int *zunionInterGetKeys(struct redisCommand *cmd,robj **argv, int argc, int *num
         *numkeys = 0;
         return NULL;
     }
-    keys = zmalloc(sizeof(int)*num);
+
+    /* Keys in z{union,inter}store come from two places:
+       argv[1] = storage key,
+       argv[3...n] = keys to intersect */
+
+    /* (num+1) is (argv[2] + 1) to account for argv[1] too */
+    keys = zmalloc(sizeof(int)*(num+1));
+
+    /* Add all key positions for argv[3...n] to keys[] */
     for (i = 0; i < num; i++) keys[i] = 3+i;
-    *numkeys = num;
+
+    /* Now add the argv[1] key position (the storage key target)
+       to our list of command positions containing keys.
+       num is the number of source keys, but we initialized
+       keys[] to size num+1, so keys[num] is safe and valid and okay. */
+    keys[num] = 1;
+    *numkeys = num+1;  /* Total keys = {union,inter} keys + storage key */
     return keys;
 }