This is an automated email from the ASF dual-hosted git repository.

piotr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git


The following commit(s) were added to refs/heads/master by this push:
     new d53a6c17 feat(server): verify the format of server_addr (#1770)
d53a6c17 is described below

commit d53a6c173d2cfb89f5cad32e8916f1ce6d5bc22e
Author: Cancai Cai <[email protected]>
AuthorDate: Sat May 17 23:34:47 2025 +0800

    feat(server): verify the format of server_addr (#1770)
---
 core/common/src/error/iggy_error.rs                |  2 +
 .../tcp_config/tcp_client_config_builder.rs        | 83 +++++++++++++++++++++-
 core/sdk/src/clients/client_builder.rs             |  2 +-
 3 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/core/common/src/error/iggy_error.rs 
b/core/common/src/error/iggy_error.rs
index b8076e2e..b293270b 100644
--- a/core/common/src/error/iggy_error.rs
+++ b/core/common/src/error/iggy_error.rs
@@ -77,6 +77,8 @@ pub enum IggyError {
     InvalidServerAddress = 33,
     #[error("Invalid client address")]
     InvalidClientAddress = 34,
+    #[error("Invalid IP address: {0}:{1}")]
+    InvalidIpAddress(String, String) = 35,
     #[error("Unauthenticated")]
     Unauthenticated = 40,
     #[error("Unauthorized")]
diff --git 
a/core/common/src/types/configuration/tcp_config/tcp_client_config_builder.rs 
b/core/common/src/types/configuration/tcp_config/tcp_client_config_builder.rs
index 8198d12e..097e9501 100644
--- 
a/core/common/src/types/configuration/tcp_config/tcp_client_config_builder.rs
+++ 
b/core/common/src/types/configuration/tcp_config/tcp_client_config_builder.rs
@@ -15,7 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use crate::{AutoLogin, IggyDuration, TcpClientConfig};
+use crate::{AutoLogin, IggyDuration, IggyError, TcpClientConfig};
+use std::net::SocketAddr;
 
 /// Builder for the TCP client configuration.
 /// Allows configuring the TCP client with custom settings or using defaults:
@@ -89,7 +90,83 @@ impl TcpClientConfigBuilder {
     }
 
     /// Builds the TCP client configuration.
-    pub fn build(self) -> TcpClientConfig {
-        self.config
+    pub fn build(self) -> Result<TcpClientConfig, IggyError> {
+        let addr = self.config.server_address.trim();
+
+        if addr.parse::<SocketAddr>().is_err() {
+            let (ip, port) = addr.rsplit_once(':').unwrap_or((addr, ""));
+            return Err(IggyError::InvalidIpAddress(ip.to_owned(), 
port.to_owned()));
+        }
+
+        Ok(self.config)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::IggyError;
+
+    fn builder_with_address(addr: &str) -> TcpClientConfigBuilder {
+        let mut builder = TcpClientConfigBuilder::default();
+        builder.config.server_address = addr.to_string();
+        builder
+    }
+
+    #[test]
+    fn valid_ipv4_should_succeed() {
+        let builder = builder_with_address("127.0.0.1:8080");
+        assert!(builder.build().is_ok());
+    }
+
+    #[test]
+    fn valid_ipv6_with_brackets_should_succeed() {
+        let builder = builder_with_address("[::1]:8080");
+        assert!(builder.build().is_ok());
+    }
+
+    #[test]
+    fn valid_ipv6_without_brackets_should_fail() {
+        let builder = builder_with_address("::1:8080");
+        assert!(matches!(
+            builder.build(),
+            Err(IggyError::InvalidIpAddress(_, _))
+        ));
+    }
+
+    #[test]
+    fn invalid_ip_should_fail() {
+        let builder = builder_with_address("invalid.ip:8080");
+        assert!(matches!(
+            builder.build(),
+            Err(IggyError::InvalidIpAddress(_, _))
+        ));
+    }
+
+    #[test]
+    fn invalid_port_should_fail() {
+        let builder = builder_with_address("127.0.0.1:invalid");
+        assert!(matches!(
+            builder.build(),
+            Err(IggyError::InvalidIpAddress(_, _))
+        ));
+    }
+
+    #[test]
+    fn ipv6_missing_closing_bracket_should_fail() {
+        let builder = builder_with_address("[::1:8080");
+        assert!(matches!(
+            builder.build(),
+            Err(IggyError::InvalidIpAddress(_, _))
+        ));
+    }
+
+    #[test]
+    fn missing_port_should_fail() {
+        let builder = builder_with_address("127.0.0.1");
+        assert!(matches!(
+            builder.build(),
+            Err(IggyError::InvalidIpAddress(_, _))
+        ));
     }
 }
diff --git a/core/sdk/src/clients/client_builder.rs 
b/core/sdk/src/clients/client_builder.rs
index 0e5fd886..2c048399 100644
--- a/core/sdk/src/clients/client_builder.rs
+++ b/core/sdk/src/clients/client_builder.rs
@@ -174,7 +174,7 @@ impl TcpClientBuilder {
 
     /// Builds the parent `IggyClient` with TCP configuration.
     pub fn build(self) -> Result<IggyClient, IggyError> {
-        let client = TcpClient::create(Arc::new(self.config.build()))?;
+        let client = TcpClient::create(Arc::new(self.config.build()?))?;
         let client = 
self.parent_builder.with_client(Box::new(client)).build()?;
         Ok(client)
     }

Reply via email to