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 4e9da19 fix: give in operator the same precedence as comparison
operators
4e9da19 is described below
commit 4e9da1908ab82ff917f1ab8ca91fce69d6fd0ec0
Author: Yang Luo <[email protected]>
AuthorDate: Tue Oct 20 21:57:39 2026 +0800
fix: give in operator the same precedence as comparison operators
---
src/coreEnforcer.ts | 2 +-
test/model.test.ts | 19 ++++++++++++++++++-
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/src/coreEnforcer.ts b/src/coreEnforcer.ts
index a18494f..824fc95 100644
--- a/src/coreEnforcer.ts
+++ b/src/coreEnforcer.ts
@@ -82,7 +82,7 @@ export class CoreEnforcer {
private getExpression(asyncCompile: boolean, exp: string): Matcher {
const matcherKey = `${asyncCompile ? 'ASYNC[' : 'SYNC['}${exp}]`;
- addBinaryOp('in', 1, customIn);
+ addBinaryOp('in', 6, customIn);
let expression = this.matcherMap.get(matcherKey);
if (!expression) {
diff --git a/test/model.test.ts b/test/model.test.ts
index 4fccab4..a847fb2 100644
--- a/test/model.test.ts
+++ b/test/model.test.ts
@@ -13,7 +13,7 @@
// limitations under the License.
// noinspection JSMismatchedCollectionQueryUpdate
-import { DefaultRoleManager, Enforcer, newEnforcer, newModel } from '../src';
+import { DefaultRoleManager, Enforcer, newEnforcer, newModel, StringAdapter }
from '../src';
import { keyMatch2Func, keyMatch3Func, keyMatchFunc } from '../src/util';
async function testEnforce(e: Enforcer, sub: string, obj: any, act: string,
res: boolean): Promise<void> {
@@ -459,3 +459,20 @@ test('ABACModelWithInOperator', async () => {
await expect(e.enforce(rule1, rule2)).resolves.toBe(true);
});
+
+test('InOperatorPrecedence', async () => {
+ const run = async (matcher: string, sub: string, obj: any): Promise<boolean>
=> {
+ const m = newModel();
+ m.addDef('r', 'r', 'sub, obj');
+ m.addDef('p', 'p', 'sub');
+ m.addDef('e', 'e', 'some(where (p.eft == allow))');
+ m.addDef('m', 'm', matcher);
+ return newEnforcer(m, new StringAdapter('p, admin')).then((e) =>
e.enforce(sub, obj));
+ };
+
+ await expect(run('r.sub == p.sub && r.obj.IsPublic in [false]', 'guest', {
IsPublic: false })).resolves.toBe(false);
+ await expect(run('r.sub == p.sub && r.obj.IsPublic in [false]', 'admin', {
IsPublic: false })).resolves.toBe(true);
+ await expect(run('r.sub == p.sub || r.obj.Name in ["a"]', 'admin', { Name:
'b' })).resolves.toBe(true);
+ await expect(run('r.sub == p.sub || r.obj.Name in ["a"]', 'guest', { Name:
'a' })).resolves.toBe(true);
+ await expect(run('r.sub == p.sub || r.obj.Name in ["a"]', 'guest', { Name:
'b' })).resolves.toBe(false);
+});
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]