Skip to content

Commit b12c8f8

Browse files
committed
Fix review to prevent heartbeat interval overflow
Signed-off-by: Viet Nguyen Duc <[email protected]>
1 parent cc71cd0 commit b12c8f8

File tree

1 file changed

+60
-9
lines changed

1 file changed

+60
-9
lines changed

java/src/org/openqa/selenium/events/zeromq/ZmqUtils.java

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,86 @@
1818
package org.openqa.selenium.events.zeromq;
1919

2020
import java.time.Duration;
21+
import java.util.logging.Level;
2122
import java.util.logging.Logger;
2223
import org.zeromq.ZMQ;
2324

24-
/** Utility methods for ZeroMQ socket configuration. */
2525
class ZmqUtils {
2626

2727
private static final Logger LOG = Logger.getLogger(ZmqUtils.class.getName());
2828

29-
private ZmqUtils() {
30-
// Utility class
31-
}
29+
// Minimum heartbeat interval: 1 second
30+
private static final long MIN_HEARTBEAT_MS = 1_000L;
31+
// Maximum heartbeat interval: ~24 days (to prevent overflow when multiplied by 6)
32+
private static final long MAX_HEARTBEAT_MS = Integer.MAX_VALUE / 6;
33+
34+
private ZmqUtils() {}
3235

3336
/**
3437
* Configures ZeroMQ heartbeat settings on a socket to prevent stale connections.
3538
*
39+
* <p>The heartbeat interval is clamped between 1 second and ~24 days to prevent integer overflow
40+
* and ensure reasonable values. If the provided duration is outside this range, it will be
41+
* adjusted and a warning will be logged.
42+
*
3643
* @param socket The ZMQ socket to configure
3744
* @param heartbeatPeriod The heartbeat interval duration
3845
* @param socketType The socket type name for logging (e.g., "SUB", "PUB", "XPUB", "XSUB")
3946
*/
4047
static void configureHeartbeat(ZMQ.Socket socket, Duration heartbeatPeriod, String socketType) {
4148
if (heartbeatPeriod != null && !heartbeatPeriod.isZero() && !heartbeatPeriod.isNegative()) {
42-
int heartbeatIvl = (int) heartbeatPeriod.toMillis();
49+
long heartbeatMs = heartbeatPeriod.toMillis();
50+
long clampedHeartbeatMs = clampHeartbeatInterval(heartbeatMs, socketType);
51+
52+
// Safe to cast to int now
53+
int heartbeatIvl = (int) clampedHeartbeatMs;
54+
int heartbeatTimeout = heartbeatIvl * 3;
55+
int heartbeatTtl = heartbeatIvl * 6;
56+
4357
socket.setHeartbeatIvl(heartbeatIvl);
44-
socket.setHeartbeatTimeout(heartbeatIvl * 3);
45-
socket.setHeartbeatTtl(heartbeatIvl * 6);
58+
socket.setHeartbeatTimeout(heartbeatTimeout);
59+
socket.setHeartbeatTtl(heartbeatTtl);
60+
4661
LOG.info(
4762
String.format(
48-
"ZMQ %s socket heartbeat configured: interval=%dms, timeout=%dms, ttl=%dms",
49-
socketType, heartbeatIvl, heartbeatIvl * 3, heartbeatIvl * 6));
63+
"ZMQ %s socket heartbeat configured: interval=%ds, timeout=%ds, ttl=%ds",
64+
socketType, heartbeatIvl / 1000, heartbeatTimeout / 1000, heartbeatTtl / 1000));
65+
}
66+
}
67+
68+
/**
69+
* Clamps the heartbeat interval to safe bounds and logs warnings if adjustments are made.
70+
*
71+
* @param heartbeatMs The heartbeat interval in milliseconds
72+
* @param socketType The socket type for logging
73+
* @return The clamped heartbeat interval
74+
*/
75+
private static long clampHeartbeatInterval(long heartbeatMs, String socketType) {
76+
if (heartbeatMs < MIN_HEARTBEAT_MS) {
77+
logHeartbeatClampWarning(socketType, heartbeatMs, MIN_HEARTBEAT_MS, "below minimum");
78+
return MIN_HEARTBEAT_MS;
5079
}
80+
if (heartbeatMs > MAX_HEARTBEAT_MS) {
81+
logHeartbeatClampWarning(socketType, heartbeatMs, MAX_HEARTBEAT_MS, "exceeds maximum");
82+
return MAX_HEARTBEAT_MS;
83+
}
84+
return heartbeatMs;
85+
}
86+
87+
/**
88+
* Logs a warning when the heartbeat interval is clamped.
89+
*
90+
* @param socketType The socket type
91+
* @param originalMs The original interval value in milliseconds
92+
* @param clampedMs The clamped interval value in milliseconds
93+
* @param reason The reason for clamping
94+
*/
95+
private static void logHeartbeatClampWarning(
96+
String socketType, long originalMs, long clampedMs, String reason) {
97+
LOG.log(
98+
Level.WARNING,
99+
String.format(
100+
"ZMQ %s socket heartbeat interval %ds %s %ds, clamping to %ds",
101+
socketType, originalMs / 1000, reason, clampedMs / 1000, clampedMs / 1000));
51102
}
52103
}

0 commit comments

Comments
 (0)