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

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


The following commit(s) were added to refs/heads/master by this push:
     new c92cc6a  fix: return an error instead of panicking on invalid IPMatch 
input
c92cc6a is described below

commit c92cc6a070e65dc621210c8d451de3092683cd1c
Author: Yang Luo <[email protected]>
AuthorDate: Thu Nov 5 01:03:28 2026 +0800

    fix: return an error instead of panicking on invalid IPMatch input
---
 error_test.go                  | 14 ++++++++++++++
 util/builtin_operators.go      | 29 ++++++++++++++++++++---------
 util/builtin_operators_test.go |  4 ++++
 3 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/error_test.go b/error_test.go
index 5ee2d40..c608422 100644
--- a/error_test.go
+++ b/error_test.go
@@ -320,6 +320,20 @@ func TestInvalidPatternInPolicy(t *testing.T) {
        }
 }
 
+func TestInvalidIPInRequest(t *testing.T) {
+       e, err := NewEnforcer("examples/ipmatch_model.conf", 
"examples/ipmatch_policy.csv")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       _, err = e.Enforce("192.168.2.abc", "data1", "read")
+       if err == nil || strings.HasPrefix(err.Error(), "panic:") ||
+               !strings.Contains(err.Error(), `ipMatch: "192.168.2.abc" is not 
an IP address`) {
+               t.Errorf("Enforce returns %v, supposed to be an ipMatch 
argument error", err)
+       }
+       testEnforce(t, e, "192.168.2.1", "data1", "read", true)
+}
+
 func TestPatternWithCaptureGroupInPolicy(t *testing.T) {
        e, err := NewEnforcer("examples/rbac_with_pattern_model.conf")
        if err != nil {
diff --git a/util/builtin_operators.go b/util/builtin_operators.go
index 87ed875..cfed09d 100644
--- a/util/builtin_operators.go
+++ b/util/builtin_operators.go
@@ -588,23 +588,29 @@ func RegexMatchFunc(args ...interface{}) (interface{}, 
error) {
 
 // IPMatch determines whether IP address ip1 matches the pattern of IP address 
ip2, ip2 can be an IP address or a CIDR pattern.
 // For example, "192.168.2.123" matches "192.168.2.0/24".
+// An invalid argument matches nothing; IPMatchFunc reports it as an error.
 func IPMatch(ip1 string, ip2 string) bool {
+       matched, _ := ipMatch(ip1, ip2)
+       return matched
+}
+
+func ipMatch(ip1 string, ip2 string) (bool, error) {
        objIP1 := net.ParseIP(ip1)
        if objIP1 == nil {
-               panic("invalid argument: ip1 in IPMatch() function is not an IP 
address.")
+               return false, fmt.Errorf("%q is not an IP address", ip1)
        }
 
        _, cidr, err := net.ParseCIDR(ip2)
-       if err != nil {
-               objIP2 := net.ParseIP(ip2)
-               if objIP2 == nil {
-                       panic("invalid argument: ip2 in IPMatch() function is 
neither an IP address nor a CIDR.")
-               }
+       if err == nil {
+               return cidr.Contains(objIP1), nil
+       }
 
-               return objIP1.Equal(objIP2)
+       objIP2 := net.ParseIP(ip2)
+       if objIP2 == nil {
+               return false, fmt.Errorf("%q is neither an IP address nor a 
CIDR", ip2)
        }
 
-       return cidr.Contains(objIP1)
+       return objIP1.Equal(objIP2), nil
 }
 
 // IPMatchFunc is the wrapper for IPMatch.
@@ -616,7 +622,12 @@ func IPMatchFunc(args ...interface{}) (interface{}, error) 
{
        ip1 := args[0].(string)
        ip2 := args[1].(string)
 
-       return IPMatch(ip1, ip2), nil
+       matched, err := ipMatch(ip1, ip2)
+       if err != nil {
+               return false, fmt.Errorf("%s: %w", "ipMatch", err)
+       }
+
+       return matched, nil
 }
 
 // GlobMatch determines whether key1 matches the pattern of key2 using glob 
pattern.
diff --git a/util/builtin_operators_test.go b/util/builtin_operators_test.go
index c9445d3..2b64b62 100644
--- a/util/builtin_operators_test.go
+++ b/util/builtin_operators_test.go
@@ -340,6 +340,8 @@ func TestIPMatch(t *testing.T) {
        testIPMatch(t, "192.168.2.123", "192.168.2.123/32", true)
        testIPMatch(t, "10.0.0.11", "10.0.0.0/8", true)
        testIPMatch(t, "11.0.0.123", "10.0.0.0/8", false)
+       testIPMatch(t, "192.168.2.abc", "192.168.2.0/24", false)
+       testIPMatch(t, "192.168.2.123", "not-an-ip", false)
 }
 
 func testRegexMatchFunc(t *testing.T, res bool, err string, args 
...interface{}) {
@@ -631,6 +633,8 @@ func TestIPMatchFunc(t *testing.T) {
        testIPMatchFunc(t, false, "ipMatch: expected 2 arguments, but got 1", 
"192.168.2.123")
        testIPMatchFunc(t, false, "ipMatch: argument must be a string", 
"192.168.2.123", 128)
        testIPMatchFunc(t, true, "", "192.168.2.123", "192.168.2.0/24")
+       testIPMatchFunc(t, false, `ipMatch: "192.168.2.abc" is not an IP 
address`, "192.168.2.abc", "192.168.2.0/24")
+       testIPMatchFunc(t, false, `ipMatch: "not-an-ip" is neither an IP 
address nor a CIDR`, "192.168.2.123", "not-an-ip")
 }
 
 func TestGlobMatch(t *testing.T) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to