mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f65685149 | |||
| ae9cae8d22 |
Generated
+10
-11
@@ -837,9 +837,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyo3"
|
name = "pyo3"
|
||||||
version = "0.28.3"
|
version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12"
|
checksum = "cd274650b21d4bfc26a0a47587962c1edb425f69287324355cd040c3ea66071c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -852,18 +852,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyo3-build-config"
|
name = "pyo3-build-config"
|
||||||
version = "0.28.3"
|
version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e"
|
checksum = "c5e2a7d2f0d013342f295c048ad19237add5154a55b1c5a254c0ec93d4109078"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyo3-ffi"
|
name = "pyo3-ffi"
|
||||||
version = "0.28.3"
|
version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e"
|
checksum = "ca85c467da1bbc8d866eea5deff9cf29ea5f7785054a17da36e65bda9c05845b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"pyo3-build-config",
|
"pyo3-build-config",
|
||||||
@@ -871,9 +871,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyo3-macros"
|
name = "pyo3-macros"
|
||||||
version = "0.28.3"
|
version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df6e520eff47c45997d2fc7dd8214b25dd1310918bbb2642156ef66a67f29813"
|
checksum = "9ac53762fd065daa3194dd09337a38bd793a188100fd1a9304c4ab312d901771"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"pyo3-macros-backend",
|
"pyo3-macros-backend",
|
||||||
@@ -883,13 +883,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyo3-macros-backend"
|
name = "pyo3-macros-backend"
|
||||||
version = "0.28.3"
|
version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4cdc218d835738f81c2338f822078af45b4afdf8b2e33cbb5916f108b813acb"
|
checksum = "4ca3a1557399783172dc5bf39cfca835157732532cba56b71d2292161e53b362"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"pyo3-build-config",
|
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ coverage = ["regorus/coverage"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
ordered-float = "5.3.0"
|
ordered-float = "5.3.0"
|
||||||
pyo3 = { version = "0.28.3", features = ["abi3-py310", "anyhow", "extension-module"] }
|
pyo3 = { version = "0.29.0", features = ["abi3-py310", "anyhow", "extension-module"] }
|
||||||
regorus = { path = "../..", default-features = false, features = ["arc", "rvm"] }
|
regorus = { path = "../..", default-features = false, features = ["arc", "rvm"] }
|
||||||
serde_json = "1.0.150"
|
serde_json = "1.0.150"
|
||||||
|
|
||||||
|
|||||||
+5
-35
@@ -354,33 +354,6 @@ impl<'source> Parser<'source> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a field name after `.` in a ref expression.
|
|
||||||
///
|
|
||||||
/// Unlike [`Self::parse_var`] and [`Self::parse_ident`], this method accepts **any**
|
|
||||||
/// `TokenKind::Ident` token, including reserved keywords (e.g. `as`, `default`, `else`,
|
|
||||||
/// `false`, `if`, `import`, `in`, `not`, `null`, `package`, `some`, `true`, `with`).
|
|
||||||
///
|
|
||||||
/// The position immediately after `.` is unambiguously a field name, so there is no
|
|
||||||
/// syntactic ambiguity with statement-level keywords. This matches OPA's
|
|
||||||
/// `keywords_in_refs` capability, which is enabled by default in standard OPA builds.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
/// ```rego
|
|
||||||
/// allow if { input.v0.package.format == "npm" } # `package` is a keyword but valid here
|
|
||||||
/// ```
|
|
||||||
fn parse_ref_field(&mut self) -> Result<Span> {
|
|
||||||
let span = self.tok.1.clone();
|
|
||||||
match self.tok.0 {
|
|
||||||
TokenKind::Ident => {
|
|
||||||
self.next_token()?;
|
|
||||||
Ok(span)
|
|
||||||
}
|
|
||||||
_ => Err(self
|
|
||||||
.source
|
|
||||||
.error(self.tok.1.line, self.tok.1.col, "expecting identifier")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_number(&mut self, span: Span) -> Result<Expr> {
|
fn read_number(&mut self, span: Span) -> Result<Expr> {
|
||||||
match Number::from_str(span.text()) {
|
match Number::from_str(span.text()) {
|
||||||
Ok(v) => Ok(Expr::Number {
|
Ok(v) => Ok(Expr::Number {
|
||||||
@@ -770,10 +743,9 @@ impl<'source> Parser<'source> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
"." => {
|
"." => {
|
||||||
// Read identifier. Keywords are allowed as field names in
|
// Read identifier.
|
||||||
// dot-notation refs (e.g. `input.package.name`).
|
|
||||||
self.next_token()?;
|
self.next_token()?;
|
||||||
let field = self.parse_ref_field()?;
|
let field = self.parse_var()?;
|
||||||
span.end = self.end;
|
span.end = self.end;
|
||||||
|
|
||||||
// Disallow any whitespace between . and identifier.
|
// Disallow any whitespace between . and identifier.
|
||||||
@@ -1446,10 +1418,9 @@ impl<'source> Parser<'source> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
"." => {
|
"." => {
|
||||||
// Read identifier. Keywords are allowed as field names in
|
// Read identifier.
|
||||||
// dot-notation refs (e.g. `import data.my.package`).
|
|
||||||
self.next_token()?;
|
self.next_token()?;
|
||||||
let field = self.parse_ref_field()?;
|
let field = self.parse_ident()?;
|
||||||
span.end = self.end;
|
span.end = self.end;
|
||||||
|
|
||||||
// Disallow any whitespace between . and identifier.
|
// Disallow any whitespace between . and identifier.
|
||||||
@@ -1552,8 +1523,7 @@ impl<'source> Parser<'source> {
|
|||||||
"." => {
|
"." => {
|
||||||
let sep_pos = self.tok.1.start;
|
let sep_pos = self.tok.1.start;
|
||||||
self.next_token()?;
|
self.next_token()?;
|
||||||
// Keywords are allowed as field names in dot-notation refs.
|
let field = self.parse_var()?;
|
||||||
let field = self.parse_ref_field()?;
|
|
||||||
span.end = self.end;
|
span.end = self.end;
|
||||||
|
|
||||||
// Disallow any whitespace between . and identifier.
|
// Disallow any whitespace between . and identifier.
|
||||||
|
|||||||
@@ -1,268 +0,0 @@
|
|||||||
# Copyright (c) Microsoft Corporation.
|
|
||||||
# Licensed under the MIT License.
|
|
||||||
#
|
|
||||||
# Tests for keywords-as-field-names in dot-notation refs.
|
|
||||||
# Matches OPA's `keywords_in_refs` behavior, enabled by default.
|
|
||||||
cases:
|
|
||||||
- note: keywords_in_refs/package field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
allow if {
|
|
||||||
input.v0.package.format == "npm"
|
|
||||||
}
|
|
||||||
input:
|
|
||||||
v0:
|
|
||||||
package:
|
|
||||||
format: npm
|
|
||||||
query: data.test.allow
|
|
||||||
want_result: true
|
|
||||||
|
|
||||||
- note: keywords_in_refs/as field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.as.type
|
|
||||||
input:
|
|
||||||
as:
|
|
||||||
type: string
|
|
||||||
query: data.test.x
|
|
||||||
want_result: string
|
|
||||||
|
|
||||||
- note: keywords_in_refs/default field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.default.value
|
|
||||||
input:
|
|
||||||
default:
|
|
||||||
value: 42
|
|
||||||
query: data.test.x
|
|
||||||
want_result: 42
|
|
||||||
|
|
||||||
- note: keywords_in_refs/else field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.else.value
|
|
||||||
input:
|
|
||||||
else:
|
|
||||||
value: hello
|
|
||||||
query: data.test.x
|
|
||||||
want_result: hello
|
|
||||||
|
|
||||||
- note: keywords_in_refs/import field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.import.name
|
|
||||||
input:
|
|
||||||
import:
|
|
||||||
name: foo
|
|
||||||
query: data.test.x
|
|
||||||
want_result: foo
|
|
||||||
|
|
||||||
- note: keywords_in_refs/not field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.not.allowed
|
|
||||||
input:
|
|
||||||
not:
|
|
||||||
allowed: false
|
|
||||||
query: data.test.x
|
|
||||||
want_result: false
|
|
||||||
|
|
||||||
- note: keywords_in_refs/null field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.null.value
|
|
||||||
input:
|
|
||||||
"null":
|
|
||||||
value: 1
|
|
||||||
query: data.test.x
|
|
||||||
want_result: 1
|
|
||||||
|
|
||||||
- note: keywords_in_refs/some field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.some.field
|
|
||||||
input:
|
|
||||||
some:
|
|
||||||
field: bar
|
|
||||||
query: data.test.x
|
|
||||||
want_result: bar
|
|
||||||
|
|
||||||
- note: keywords_in_refs/true field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.true.x
|
|
||||||
input:
|
|
||||||
"true":
|
|
||||||
x: 2
|
|
||||||
query: data.test.x
|
|
||||||
want_result: 2
|
|
||||||
|
|
||||||
- note: keywords_in_refs/false field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.false.x
|
|
||||||
input:
|
|
||||||
"false":
|
|
||||||
x: 3
|
|
||||||
query: data.test.x
|
|
||||||
want_result: 3
|
|
||||||
|
|
||||||
- note: keywords_in_refs/with field
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.with.config
|
|
||||||
input:
|
|
||||||
with:
|
|
||||||
config: test
|
|
||||||
query: data.test.x
|
|
||||||
want_result: test
|
|
||||||
|
|
||||||
- note: keywords_in_refs/future keywords (if, in, every, contains)
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
import future.keywords
|
|
||||||
x if {
|
|
||||||
input.if.condition == true
|
|
||||||
input.in.set == "member"
|
|
||||||
input.every.item == "x"
|
|
||||||
input.contains.key == "val"
|
|
||||||
}
|
|
||||||
input:
|
|
||||||
if:
|
|
||||||
condition: true
|
|
||||||
in:
|
|
||||||
set: member
|
|
||||||
every:
|
|
||||||
item: x
|
|
||||||
contains:
|
|
||||||
key: val
|
|
||||||
query: data.test.x
|
|
||||||
want_result: true
|
|
||||||
|
|
||||||
- note: keywords_in_refs/chained keywords
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.package.import.default
|
|
||||||
input:
|
|
||||||
package:
|
|
||||||
import:
|
|
||||||
default: chained
|
|
||||||
query: data.test.x
|
|
||||||
want_result: chained
|
|
||||||
|
|
||||||
- note: keywords_in_refs/data path with keyword
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = data.mydata.package.name
|
|
||||||
data:
|
|
||||||
mydata:
|
|
||||||
package:
|
|
||||||
name: mypackage
|
|
||||||
query: data.test.x
|
|
||||||
want_result: mypackage
|
|
||||||
|
|
||||||
- note: keywords_in_refs/rego v1 all keywords
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
import rego.v1
|
|
||||||
allow if {
|
|
||||||
input.package.format == "npm"
|
|
||||||
input.default.value == 1
|
|
||||||
input.if.enabled == true
|
|
||||||
input.in.set == "member"
|
|
||||||
input.not.flag == false
|
|
||||||
input.with.config == "ok"
|
|
||||||
}
|
|
||||||
input:
|
|
||||||
package:
|
|
||||||
format: npm
|
|
||||||
default:
|
|
||||||
value: 1
|
|
||||||
if:
|
|
||||||
enabled: true
|
|
||||||
in:
|
|
||||||
set: member
|
|
||||||
not:
|
|
||||||
flag: false
|
|
||||||
with:
|
|
||||||
config: ok
|
|
||||||
query: data.test.allow
|
|
||||||
want_result: true
|
|
||||||
|
|
||||||
- note: keywords_in_refs/future keywords without import
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = [input.if.flag, input.in.value, input.every.item, input.contains.key]
|
|
||||||
input:
|
|
||||||
if:
|
|
||||||
flag: true
|
|
||||||
in:
|
|
||||||
value: member
|
|
||||||
every:
|
|
||||||
item: each
|
|
||||||
contains:
|
|
||||||
key: present
|
|
||||||
query: data.test.x
|
|
||||||
want_result: [true, "member", "each", "present"]
|
|
||||||
|
|
||||||
- note: keywords_in_refs/package path keywords
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package words.if.default
|
|
||||||
value = 7
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = data.words.if.default.value
|
|
||||||
query: data.test.x
|
|
||||||
want_result: 7
|
|
||||||
|
|
||||||
- note: keywords_in_refs/import path keywords
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
import data.catalog.if.default as kw
|
|
||||||
x = kw.value
|
|
||||||
data:
|
|
||||||
catalog:
|
|
||||||
if:
|
|
||||||
default:
|
|
||||||
value: 99
|
|
||||||
query: data.test.x
|
|
||||||
want_result: 99
|
|
||||||
|
|
||||||
- note: keywords_in_refs/rule head keyword path
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
policy.default.level := 3
|
|
||||||
query: data.test.policy.default.level
|
|
||||||
want_result: 3
|
|
||||||
|
|
||||||
- note: keywords_in_refs/mixed dot keyword and dynamic bracket
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
x = input.package[segment].value
|
|
||||||
segment = "import"
|
|
||||||
input:
|
|
||||||
package:
|
|
||||||
import:
|
|
||||||
value: from_dynamic
|
|
||||||
query: data.test.x
|
|
||||||
want_result: from_dynamic
|
|
||||||
@@ -315,109 +315,3 @@ cases:
|
|||||||
}
|
}
|
||||||
query: data.test.main
|
query: data.test.main
|
||||||
want_result: "/api/v1/users"
|
want_result: "/api/v1/users"
|
||||||
|
|
||||||
- note: keywords_in_refs/package_field
|
|
||||||
data: {}
|
|
||||||
input:
|
|
||||||
v0:
|
|
||||||
package:
|
|
||||||
format: npm
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
allow := true if {
|
|
||||||
input.v0.package.format == "npm"
|
|
||||||
}
|
|
||||||
query: data.test.allow
|
|
||||||
want_result: true
|
|
||||||
|
|
||||||
- note: keywords_in_refs/multiple_keywords
|
|
||||||
data: {}
|
|
||||||
input:
|
|
||||||
default:
|
|
||||||
value: 42
|
|
||||||
import:
|
|
||||||
name: foo
|
|
||||||
not:
|
|
||||||
allowed: false
|
|
||||||
with:
|
|
||||||
config: ok
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
import rego.v1
|
|
||||||
result if {
|
|
||||||
input.default.value == 42
|
|
||||||
input.import.name == "foo"
|
|
||||||
input.not.allowed == false
|
|
||||||
input.with.config == "ok"
|
|
||||||
}
|
|
||||||
query: data.test.result
|
|
||||||
want_result: true
|
|
||||||
|
|
||||||
- note: keywords_in_refs/future_keywords_without_import
|
|
||||||
data: {}
|
|
||||||
input:
|
|
||||||
if:
|
|
||||||
flag: true
|
|
||||||
in:
|
|
||||||
value: member
|
|
||||||
every:
|
|
||||||
item: each
|
|
||||||
contains:
|
|
||||||
key: present
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
result := [input.if.flag, input.in.value, input.every.item, input.contains.key]
|
|
||||||
query: data.test.result
|
|
||||||
want_result: [true, "member", "each", "present"]
|
|
||||||
|
|
||||||
- note: keywords_in_refs/package_path_keywords
|
|
||||||
data: {}
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package words.if.default
|
|
||||||
value := 7
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
result := data.words.if.default.value
|
|
||||||
query: data.test.result
|
|
||||||
want_result: 7
|
|
||||||
|
|
||||||
- note: keywords_in_refs/import_path_keywords
|
|
||||||
data:
|
|
||||||
catalog:
|
|
||||||
if:
|
|
||||||
default:
|
|
||||||
value: 99
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
import data.catalog.if.default as kw
|
|
||||||
result := kw.value
|
|
||||||
query: data.test.result
|
|
||||||
want_result: 99
|
|
||||||
|
|
||||||
- note: keywords_in_refs/rule_head_keyword_path
|
|
||||||
data: {}
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
policy.default.level := 3
|
|
||||||
query: data.test.policy.default.level
|
|
||||||
want_result: 3
|
|
||||||
|
|
||||||
- note: keywords_in_refs/mixed_dot_keyword_and_dynamic_bracket
|
|
||||||
data: {}
|
|
||||||
input:
|
|
||||||
package:
|
|
||||||
import:
|
|
||||||
value: from_dynamic
|
|
||||||
modules:
|
|
||||||
- |
|
|
||||||
package test
|
|
||||||
segment := "import"
|
|
||||||
result := input.package[segment].value
|
|
||||||
query: data.test.result
|
|
||||||
want_result: "from_dynamic"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user