The code of _unsigned long zslGetRank(zskiplist zsl, double score, robj o) _ can be found in t_zset.c

unsigned long zslGetRank(zskiplist *zsl, double score, sds ele) {
    zskiplistNode *x;
    unsigned long rank = 0;
    int i;
    x = zsl->header;
    for (i = zsl->level-1; i >= 0; i--) {
        while (x->level[i].forward &&
            (x->level[i].forward->score < score ||
                (x->level[i].forward->score == score &&
                sdscmp(x->level[i].forward->ele,ele) <= 0))) {
            rank += x->level[i].span;
            x = x->level[i].forward;
        }

    /* x might be equal to zsl->header, so test if obj is non-NULL */
    if (x->ele && sdscmp(x->ele,ele) == 0) {
        return rank;
    }
}
return 0;

}

It seems that the function will return rank even when there is no corresponding score in the SkipList. x may stop at a point when x->level[i].forward->score > score and x -> score < score. if x->obj is equal to robj* o as well, then the rank is returned, even though the score does not match.

When Redis use this function, it is used with dict; therefore this may be why it does not cause a problem for now. But for robustness and consistency of API (it does return 0 for unfound objects), shouldn't we check the score as well?