Skip to content

Commit ecf0620

Browse files
committed
Fix negative index risk when hashing Integer.MIN_VALUE (#487)
1 parent f985497 commit ecf0620

11 files changed

Lines changed: 30 additions & 16 deletions

File tree

camellia-admin/camellia-dashboard/src/main/java/com/netease/nim/camellia/dashboard/controller/AdminController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ public WebResult mock(@RequestParam("tid") long tid,
354354
int bucketSize = shardingTable.getBucketSize();
355355
DefaultShardingFunc shardingFunc = new DefaultShardingFunc();
356356
int shardingCode = shardingFunc.shardingCode(key.getBytes(StandardCharsets.UTF_8));
357-
int index = Math.abs(shardingCode) % bucketSize;
357+
int index = (shardingCode == Integer.MIN_VALUE ? 0 : Math.abs(shardingCode)) % bucketSize;
358358
ResourceOperation resourceOperation = shardingTable.getResourceOperationMap().get(index);
359359
Object ret = ReadableResourceTableUtil.readableResourceOperation(resourceOperation);
360360
LogBean.get().addProps("ret", ret);

camellia-core/src/main/java/com/netease/nim/camellia/core/discovery/HashCamelliaServerSelector.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public T pick(List<T> list, Object loadBalanceKey) {
2727
if (loadBalanceKey == null) {
2828
index = ThreadLocalRandom.current().nextInt(list.size());
2929
} else {
30-
index = Math.abs(loadBalanceKey.hashCode()) % list.size();
30+
int hash = loadBalanceKey.hashCode();
31+
index = (hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % list.size();
3132
}
3233
if (GlobalDiscoveryEnv.logInfoEnable) {
3334
logger.info("pick server by hash, loadBalanceKey = {}, index = {}, list = {}", loadBalanceKey, index, list);

camellia-feign-client/camellia-feign/src/main/java/com/netease/nim/camellia/feign/GlobalCamelliaFeignEnv.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ public int selectLoadBalanceCode(Object loadBalanceKey) {
140140
if (resourceList == null || resourceList.isEmpty()) {
141141
return -1;
142142
}
143-
return Math.abs(loadBalanceKey.hashCode()) % resourceList.size();
143+
int hash = loadBalanceKey.hashCode();
144+
return (hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % resourceList.size();
144145
}
145146
return -1;
146147
}

camellia-hot-key/camellia-hot-key-sdk/src/main/java/com/netease/nim/camellia/hot/key/sdk/netty/HotKeyClientHub.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ private HotKeyClient select0(String name, String key) {
140140
if (addrs == null || addrs.isEmpty()) {
141141
return null;
142142
}
143-
int index = Math.abs(key.hashCode()) % addrs.size();
143+
int hash = key.hashCode();
144+
int index = (hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % addrs.size();
144145
ServerNode addr = addrs.get(index);
145146
ConcurrentHashMap<ServerNode, HotKeyClientGroup> map = clientGroupMap.get(name);
146147
if (map == null || map.isEmpty()) {

camellia-id-gen/camellia-id-gen-core/src/main/java/com/netease/nim/camellia/id/gen/snowflake/RedisWorkerIdGen.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public long genWorkerId(long maxWorkerId) {
5757
} catch (Exception e) {
5858
hostAddress = UUID.randomUUID().toString();
5959
}
60-
long initialId = Math.abs(hostAddress.hashCode()) % (maxWorkerId + 1);
60+
int hash = hostAddress.hashCode();
61+
long initialId = (hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % (maxWorkerId + 1);
6162
long workerId = initialId;
6263
do {
6364
CamelliaRedisLock redisLock = CamelliaRedisLock.newLock(template, lockKey(workerId), lockExpireMillis, lockExpireMillis);
@@ -67,7 +68,7 @@ public long genWorkerId(long maxWorkerId) {
6768
return workerId;
6869
}
6970
workerId++;
70-
workerId = Math.abs(workerId) % (maxWorkerId + 1);
71+
workerId = (workerId == Long.MIN_VALUE ? 0 : Math.abs(workerId)) % (maxWorkerId + 1);
7172
} while (workerId != initialId);
7273

7374
throw new CamelliaIdGenException("workerId gen fail");

camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/cluster/ClusterModeCommandMoveInvoker.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ private boolean checkSlotInProxyNode(ProxyClusterSlotMap clusterSlotMap, ProxyNo
138138
if (slotCache != null && System.currentTimeMillis() - slotCache.updateTime <= cacheMillis) {
139139
return slotCache.slots.contains(slot);
140140
}
141-
int lockIndex = Math.abs(node.toString().hashCode()) % 32;
141+
int hash = node.toString().hashCode();
142+
int lockIndex = (hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % 32;
142143
ReentrantLock lock = lockArray[lockIndex];
143144
lock.lock();
144145
try {

camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/sentinel/DefaultSentinelModeProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,8 @@ private ProxyNode selectOnlineNode(ChannelInfo channelInfo) {
439439
id = UUID.randomUUID().toString();
440440
}
441441
int size = onlineNodes.size();
442-
int index = Math.abs(id.hashCode()) % size;
442+
int hash = id.hashCode();
443+
int index = (hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % size;
443444
target = onlineNodes.get(index);
444445
} catch (Exception e) {
445446
try {

camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/sentinel/RedisSentinelClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ public void renew() {
149149
private void renew0() {
150150
try {
151151
if (!masterListenerList.isEmpty()) {
152-
int index = Math.abs(renewIndex.getAndIncrement()) % masterListenerList.size();
152+
int hash = renewIndex.getAndIncrement();
153+
int index = (hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % masterListenerList.size();
153154
RedisSentinelMasterListener masterListener = masterListenerList.get(index);
154155
masterListener.renew();
155156
}

camellia-redis-proxy/camellia-redis-proxy-core/src/main/java/com/netease/nim/camellia/redis/proxy/upstream/sentinel/RedisSentinelSlavesClient.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,12 +361,14 @@ public void renew() {
361361
private void renew0() {
362362
try {
363363
if (!masterListenerList.isEmpty()) {
364-
int index = Math.abs(masterRenewIndex.getAndIncrement()) % masterListenerList.size();
364+
int hash = masterRenewIndex.getAndIncrement();
365+
int index = (hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % masterListenerList.size();
365366
RedisSentinelMasterListener masterListener = masterListenerList.get(index);
366367
masterListener.renew();
367368
}
368369
if (!slavesListenerList.isEmpty()) {
369-
int index = Math.abs(slaveRenewIndex.getAndIncrement()) % slavesListenerList.size();
370+
int hash = slaveRenewIndex.getAndIncrement();
371+
int index = (hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % slavesListenerList.size();
370372
RedisSentinelSlavesListener slavesListener = slavesListenerList.get(index);
371373
slavesListener.renew();
372374
}

camellia-redis-proxy/camellia-redis-proxy-extensions/camellia-redis-proxy-mq/camellia-redis-proxy-mq-kafka/src/main/java/com/netease/nim/camellia/redis/proxy/mq/kafka/KafkaProducerWrapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ public void start() {
4242
public void send(ProducerRecord<byte[], byte[]> record, MqPack mqPack) {
4343
if (!isValid()) return;
4444
byte[] key = record.key();
45-
KafkaProducer<byte[], byte[]> producer = list.get(Math.abs(Arrays.hashCode(key)) % list.size());
45+
int hash = Arrays.hashCode(key);
46+
KafkaProducer<byte[], byte[]> producer = list.get((hash == Integer.MIN_VALUE ? 0 : Math.abs(hash)) % list.size());
4647
producer.send(record, (recordMetadata, e) -> {
4748
if (e != null) {
4849
valid = false;

0 commit comments

Comments
 (0)