diff --git a/kustomizer/src/yaml.rs b/kustomizer/src/yaml.rs index 8c0f3df..dd11195 100644 --- a/kustomizer/src/yaml.rs +++ b/kustomizer/src/yaml.rs @@ -2,32 +2,70 @@ use std::io::Read; use serde::de::DeserializeOwned; +/// Default options for YAML deserialization. +/// +/// Uses `strict_booleans` (YAML 1.2 behavior) so that only `true`/`false` are +/// parsed as booleans. YAML 1.1 forms like `on`/`off`/`yes`/`no` are treated +/// as plain strings, avoiding the "Norway problem" and ensuring non-string map +/// keys don't appear when these words are used as field names (e.g. `on:` in +/// Kubernetes CRDs). +const DESER_OPTS: serde_saphyr::Options = serde_saphyr::Options { + strict_booleans: true, + budget: Some(serde_saphyr::Budget { + max_reader_input_bytes: Some(256 * 1024 * 1024), + max_events: 1_000_000, + max_aliases: 50_000, + max_anchors: 50_000, + max_depth: 2_000, + max_documents: 1_024, + max_nodes: 250_000, + max_total_scalar_bytes: 64 * 1024 * 1024, + max_merge_keys: 10_000, + enforce_alias_anchor_ratio: true, + alias_anchor_min_aliases: 100, + alias_anchor_ratio_multiplier: 10, + }), + budget_report: None, + duplicate_keys: serde_saphyr::options::DuplicateKeyPolicy::Error, + alias_limits: serde_saphyr::options::AliasLimits { + max_total_replayed_events: 1_000_000, + max_replay_stack_depth: 64, + max_alias_expansions_per_anchor: usize::MAX, + }, + legacy_octal_numbers: false, + angle_conversions: false, + ignore_binary_tag_for_string: false, + no_schema: false, + with_snippet: true, + crop_radius: 64, +}; + pub fn from_str(s: &str) -> anyhow::Result where T: DeserializeOwned, { - serde_saphyr::from_str(s).map_err(Into::into) + serde_saphyr::from_str_with_options(s, DESER_OPTS).map_err(Into::into) } pub fn from_slice(s: &[u8]) -> anyhow::Result where T: DeserializeOwned, { - serde_saphyr::from_slice(s).map_err(Into::into) + serde_saphyr::from_slice_with_options(s, DESER_OPTS).map_err(Into::into) } pub fn from_reader(reader: impl Read) -> anyhow::Result where T: DeserializeOwned, { - serde_saphyr::from_reader(reader).map_err(Into::into) + serde_saphyr::from_reader_with_options(reader, DESER_OPTS).map_err(Into::into) } pub fn from_reader_multi(mut reader: impl Read) -> anyhow::Result> where T: DeserializeOwned, { - serde_saphyr::read(&mut reader) + serde_saphyr::read_with_options(&mut reader, DESER_OPTS) .map(|res| res.map_err(Into::into)) .collect() } diff --git a/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/kustomization.yaml b/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/kustomization.yaml new file mode 100644 index 0000000..8fca817 --- /dev/null +++ b/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - policy.yaml diff --git a/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/output.yaml b/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/output.yaml new file mode 100644 index 0000000..8cd850f --- /dev/null +++ b/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/output.yaml @@ -0,0 +1,30 @@ +apiVersion: pgroles.io/v1alpha1 +kind: PostgresPolicy +metadata: + name: test-policy +spec: + profiles: + editor: + grants: + - on: + type: schema + privileges: + - USAGE + - on: + type: table + name: "*" + privileges: + - SELECT + - INSERT + - UPDATE + - DELETE + roles: + - name: app_analytics + login: true + - name: some_viewer + memberships: + - role: editor + members: + - name: app_analytics + - name: some_viewer + inherit: false diff --git a/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/policy.yaml b/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/policy.yaml new file mode 100644 index 0000000..98575e1 --- /dev/null +++ b/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/policy.yaml @@ -0,0 +1,21 @@ +apiVersion: pgroles.io/v1alpha1 +kind: PostgresPolicy +metadata: + name: test-policy +spec: + profiles: + editor: + grants: + - on: {type: schema} + privileges: [USAGE] + - on: {type: table, name: "*"} + privileges: [SELECT, INSERT, UPDATE, DELETE] + roles: + - name: app_analytics + login: true + - name: some_viewer + memberships: + - role: editor + members: + - {name: app_analytics} + - {name: some_viewer, inherit: false} diff --git a/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/test.yaml b/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/test.yaml new file mode 100644 index 0000000..d559789 --- /dev/null +++ b/kustomizer/tests/kustomizer/testdata/regression/yaml11-boolean-key/test.yaml @@ -0,0 +1 @@ +name: yaml11-boolean-key