From 66f9393ee4d526e27df38e7b610daef30a4c89bd Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 31 Mar 2015 15:22:56 +0200 Subject: [PATCH] Fix setTypeNext call assuming NULL can be passed. Segfault introduced during a refactoring / warning suppression a few commits away. This particular call assumed that it is safe to pass NULL to the object pointer argument when we are sure the set has a given encoding. This can't be assumed and is now guaranteed to segfault because of the new API of setTypeNext(). --- src/t_set.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/t_set.c b/src/t_set.c index 44580098..c974c185 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -144,7 +144,11 @@ void setTypeReleaseIterator(setTypeIterator *si) { * Since set elements can be internally be stored as redis objects or * simple arrays of integers, setTypeNext returns the encoding of the * set object you are iterating, and will populate the appropriate pointer - * (eobj) or (llobj) accordingly. + * (objele) or (llele) accordingly. + * + * Note that both the objele and llele pointers should be passed and cannot + * be NULL since the function will try to defensively populate the non + * used field with values which are easy to trap if misused. * * When there are no longer elements -1 is returned. * Returned objects ref count is not incremented, so this function is @@ -201,6 +205,10 @@ robj *setTypeNextObject(setTypeIterator *si) { * field of the object and is used by the caller to check if the * int64_t pointer or the redis object pointer was populated. * + * Note that both the objele and llele pointers should be passed and cannot + * be NULL since the function will try to defensively populate the non + * used field with values which are easy to trap if misused. + * * When an object is returned (the set was a real set) the ref count * of the object is not incremented so this function can be considered * copy on write friendly. */ @@ -246,7 +254,7 @@ void setTypeConvert(robj *setobj, int enc) { /* To add the elements we extract integers and create redis objects */ si = setTypeInitIterator(setobj); - while (setTypeNext(si,NULL,&intele) != -1) { + while (setTypeNext(si,&element,&intele) != -1) { element = createStringObjectFromLongLong(intele); redisAssertWithInfo(NULL,element, dictAdd(d,element,NULL) == DICT_OK);