I use command "SADD testSet 1" to store a Set key to redis. in my module , I use RedisModule_ScanKey to iterate testSet Key。 In the ScanKey callback,redis will pass the field parameter which is encoded OBJ_ENCODING_INT。 I want to get the field string point, but RedisModuleString API return me the invalid point.

ScanKey callback code:

void mwScanSetMemberCallback(RedisModuleKey *key, RedisModuleString *field, RedisModuleString *value, void *privdata) {
    REDISMODULE_NOT_USED(key);
    REDISMODULE_NOT_USED(value);

    RedisModuleString *k = (RedisModuleString *)privdata;        //the is 0x1
    const char *f = RedisModule_StringPtrLen(field, NULL);
}

in the ScanKey function:

   // testSetKey is Set type, and the value is encoded by OBJ_ENCODING_INTSET
    } else if (o->type == OBJ_SET && o->encoding == OBJ_ENCODING_INTSET) {  
        int pos = 0;
        int64_t ll;
        while(intsetGet(o->ptr,pos++,&ll)) {
            //the field parameter is OBJ_ENCODING_INT, not String ,so the ptr is value
            robj *field = createStringObjectFromLongLong(ll);   
            fn(key, field, NULL, privdata);
            decrRefCount(field);
        }
        cursor->cursor = 1;
        cursor->done = 1;
        ret = 0;

but API think all RedisModuleString->ptr is a point

/* Given a string module object, this function returns the string pointer
 * and length of the string. The returned pointer and length should only
 * be used for read only accesses and never modified. */
const char *RM_StringPtrLen(const RedisModuleString *str, size_t *len) {
    if (str == NULL) {
        const char *errmsg = "(NULL string reply referenced in module)";
        if (len) *len = strlen(errmsg);
        return errmsg;
    }
    if (len) *len = sdslen(str->ptr);
    return str->ptr;
}

/* --------------------------------------------------------------------------
 * Higher level string operations
 * ------------------------------------------------------------------------- */

/* Convert the string into a long long integer, storing it at `*ll`.
 * Returns REDISMODULE_OK on success. If the string can't be parsed
 * as a valid, strict long long (no spaces before/after), REDISMODULE_ERR
 * is returned. */
int RM_StringToLongLong(const RedisModuleString *str, long long *ll) {
    return string2ll(str->ptr,sdslen(str->ptr),ll) ? REDISMODULE_OK :
                                                     REDISMODULE_ERR;
}

Is this a bug?

Comment From: oranagra

@YiLinice yes, it was a bug. fixed in: https://github.com/redis/redis/pull/7396. fixed in Redis 6.0.6