Skip to content

Commit ecd4eb1

Browse files
AvivDavid23claude
andcommitted
MOD-15896 Address PR review: RESP3-safe cluster-enabled parse, reuse rlec_version
- Handle both RESP2 array and RESP3 map shapes for CONFIG GET cluster-enabled, so a future RESP3 module ctx can't silently misdetect an OSS-cluster shard as enterprise. - Reuse MR_RlecMajorVersion (already parsed by MR_GetRedisVersion before MR_ClusterInit) instead of a second GetServerInfo("Server") call. - Switch the "yes" compare to memcmp for cross-repo consistency and document case-sensitivity and the load-bearing enterprise/OSS decision. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 305cdba commit ecd4eb1

1 file changed

Lines changed: 28 additions & 11 deletions

File tree

src/cluster.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,31 +1649,48 @@ int MR_ClusterInit(RedisModuleCtx* rctx, char *password) {
16491649
clusterCtx.password = password ? MR_STRDUP(password) : NULL;
16501650
memset(clusterCtx.myId, '0', REDISMODULE_NODE_ID_LEN);
16511651

1652-
RedisModuleServerInfoData *info = RedisModule_GetServerInfo(rctx, "Server");
1653-
const char *rlecVersion = RedisModule_ServerInfoGetFieldC(info, "rlec_version");
16541652
/* Note: RedisModule_GetContextFlags() does NOT report
16551653
* REDISMODULE_CTX_FLAGS_CLUSTER yet at module-load time, so read the
16561654
* cluster-enabled config directly to learn the runtime mode. */
16571655
bool ossClusterRuntime = false;
16581656
RedisModuleCallReply *ceReply = RedisModule_Call(rctx, "config", "cc", "get", "cluster-enabled");
1659-
if (ceReply && RedisModule_CallReplyType(ceReply) == REDISMODULE_REPLY_ARRAY &&
1660-
RedisModule_CallReplyLength(ceReply) >= 2) {
1661-
RedisModuleCallReply *val = RedisModule_CallReplyArrayElement(ceReply, 1);
1662-
if (RedisModule_CallReplyType(val) == REDISMODULE_REPLY_STRING) {
1657+
if (ceReply) {
1658+
/* CONFIG GET replies as a flat array in RESP2 and as a map in RESP3.
1659+
* The module ctx defaults to RESP2, but handle both shapes so a future
1660+
* RESP3 default can't silently break detection and misclassify an
1661+
* OSS-cluster shard as enterprise. */
1662+
int ceType = RedisModule_CallReplyType(ceReply);
1663+
RedisModuleCallReply *val = NULL;
1664+
if (ceType == REDISMODULE_REPLY_ARRAY && RedisModule_CallReplyLength(ceReply) >= 2) {
1665+
val = RedisModule_CallReplyArrayElement(ceReply, 1);
1666+
} else if (ceType == REDISMODULE_REPLY_MAP && RedisModule_CallReplyMapElement &&
1667+
RedisModule_CallReplyLength(ceReply) >= 1) {
1668+
RedisModule_CallReplyMapElement(ceReply, 0, NULL, &val);
1669+
}
1670+
if (val && RedisModule_CallReplyType(val) == REDISMODULE_REPLY_STRING) {
16631671
size_t vlen = 0;
16641672
const char *vstr = RedisModule_CallReplyStringPtr(val, &vlen);
1665-
if (vstr && vlen == 3 && strncmp(vstr, "yes", 3) == 0) {
1673+
/* CONFIG GET returns the canonical lowercase "yes"/"no" (Redis
1674+
* spec), so a case-sensitive compare of exactly 3 bytes is safe. */
1675+
if (vstr && vlen == 3 && memcmp(vstr, "yes", 3) == 0) {
16661676
ossClusterRuntime = true;
16671677
}
16681678
}
1669-
}
1670-
if (ceReply) {
16711679
RedisModule_FreeCallReply(ceReply);
16721680
}
1673-
if (rlecVersion && !ossClusterRuntime) {
1681+
/* rlec_version is only present on enterprise binaries. It was already
1682+
* parsed into MR_RlecMajorVersion by MR_GetRedisVersion() (run before
1683+
* MR_ClusterInit), so reuse it here instead of fetching Server info a
1684+
* second time; MR_RlecMajorVersion >= 0 means the field was present.
1685+
*
1686+
* Treat the shard as enterprise only when rlec_version is present AND we
1687+
* are not in OSS cluster mode. This is the load-bearing decision of the
1688+
* PR: it unblocks an enterprise binary running as an OSS cluster (e.g. the
1689+
* env0 testing setup), which must take the OSS path (internal-secret AUTH,
1690+
* no _proxy-filtered command flags) rather than the enterprise path. */
1691+
if (MR_RlecMajorVersion >= 0 && !ossClusterRuntime) {
16741692
clusterCtx.isOss = false;
16751693
}
1676-
RedisModule_FreeServerInfo(rctx, info);
16771694

16781695
RedisModule_Log(rctx, "notice", "Detected redis %s (cluster-enabled=%s)",
16791696
clusterCtx.isOss ? "oss" : "enterprise",

0 commit comments

Comments
 (0)