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-node-casbin.git


The following commit(s) were added to refs/heads/master by this push:
     new e1f5372  fix: avoid crash when policies change during async enforce
e1f5372 is described below

commit e1f5372f5c183c6bd84f1e77d7dee800a1d22ddf
Author: Yang Luo <[email protected]>
AuthorDate: Wed Oct 21 00:25:56 2026 +0800

    fix: avoid crash when policies change during async enforce
---
 src/coreEnforcer.ts   |  7 ++++---
 test/enforcer.test.ts | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/src/coreEnforcer.ts b/src/coreEnforcer.ts
index 824fc95..0fa1a24 100644
--- a/src/coreEnforcer.ts
+++ b/src/coreEnforcer.ts
@@ -472,7 +472,8 @@ export class CoreEnforcer {
     let expression: Matcher | undefined = undefined;
 
     const p = this.model.model.get('p')?.get(enforceContext.pType);
-    const policyLen = p?.policy?.length;
+    const policy = p?.policy ? [...p.policy] : [];
+    const policyLen = policy.length;
 
     const rTokens = 
this.model.model.get('r')?.get(enforceContext.rType)?.tokens;
     const rTokensLen = rTokens?.length;
@@ -503,7 +504,7 @@ export class CoreEnforcer {
         }
 
         p?.tokens.forEach((token, j) => {
-          parameters[token] = p?.policy[i][j];
+          parameters[token] = policy[i][j];
         });
 
         if (HasEval) {
@@ -616,7 +617,7 @@ export class CoreEnforcer {
       if (explainIndex === -1) {
         return [res, []];
       }
-      return [res, p?.policy?.[explainIndex] || []];
+      return [res, policy[explainIndex] || []];
     }
 
     return res;
diff --git a/test/enforcer.test.ts b/test/enforcer.test.ts
index 78d38a4..71af763 100644
--- a/test/enforcer.test.ts
+++ b/test/enforcer.test.ts
@@ -934,3 +934,36 @@ test('TestEnforceWithEnableAcceptJsonRequest', async () => 
{
   await testEnforce(e, sub2, '/data2', 'write', false);
   await testEnforce(e, sub3, '/data1', 'read', false);
 });
+
+test('test enforce while policies are removed during evaluation', async () => {
+  const m = newModel();
+  m.addDef('r', 'r', 'sub, obj, act');
+  m.addDef('p', 'p', 'sub, obj, act');
+  m.addDef('e', 'e', 'some(where (p.eft == allow))');
+  m.addDef('m', 'm', 'removeOthers(p.sub) && r.sub == p.sub && r.obj == p.obj 
&& r.act == p.act');
+
+  const e = await newEnforcer(m);
+  await e.addPolicies([
+    ['alice', 'data1', 'read'],
+    ['bob', 'data2', 'write'],
+    ['carol', 'data3', 'read'],
+  ]);
+
+  await e.addFunction('removeOthers', () => {
+    e.getModel().removePolicy('p', 'p', ['bob', 'data2', 'write']);
+    e.getModel().removePolicy('p', 'p', ['carol', 'data3', 'read']);
+    return true;
+  });
+
+  await testEnforce(e, 'carol', 'data3', 'read', true);
+  await e.addPolicies([
+    ['bob', 'data2', 'write'],
+    ['carol', 'data3', 'read'],
+  ]);
+  testEnforceSync(e, 'carol', 'data3', 'read', true);
+  await e.addPolicies([
+    ['bob', 'data2', 'write'],
+    ['carol', 'data3', 'read'],
+  ]);
+  await expect(e.enforceEx('carol', 'data3', 'read')).resolves.toEqual([true, 
['carol', 'data3', 'read']]);
+});


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

Reply via email to