diff --git a/MANIFEST.sha256 b/MANIFEST.sha256 index 8371d3a..a1388da 100644 --- a/MANIFEST.sha256 +++ b/MANIFEST.sha256 @@ -10,6 +10,7 @@ 11a0fb2cf1ce82ed7df0fe05a6fceb8e20051c48c4e9c80925f34d68dace503d tools/schemalib/validator.py 1264e708b92df67154f5f50bf52d9e7c5b3edb586db583dc47fc10b59bc060ab module/canonical_json.go 134ea29c14da90cff091cb9bd5406522e182a07a86c6c4203e1436df8c26c4bc docs/en/concept/declarative_ecosystem_integration.meta.yaml +139c658d3aa952a54fe5c9b6a8c0c9f3bb83345b1a28551c5c5ad9f2f0c0fdf4 module/m4a_gate_test.go 13b0b2a232d66df4fe26ec751b49b600fc63dbcde26b2bf17c675bfed78d30f8 module/testdata/vcn-v1/cases/partial-read/expected/observed.registry.json 15551f514d13c6d42283a2cf09355f900f862624a51f3e32b6675ef3a24fce4a tools/oci-extract/go.mod 1610f9791c9760be651e499bd3a22f3c65cc5c0521fc77dfe90f08ddbc72f0be module/cicflow_guest.go @@ -17,6 +18,7 @@ 17502a16b64b102182c1e2ffea7b51d9c39461dd8c9dbaad4427ce8ffd213bbf module/testdata/vcn-v1/cases/transport-error/expected/observed.registry.json 1b3e25bf2122e2d44a8cfc13620797fd129911c5c74d8e1c1db96cee6994f1ce docs/hu/concept/git-management.meta.yaml 1b6261e82d3a60e8f5b479fd68b9f097bf750d1e516d345dd50266af3ef085fc tests/test_wasm_fresh_guest_gate.py +1c1ce6b3ef9b99975b9b4653ac85647a930178d9c1ffed50d2a54ddf67db7de9 module/plan_noop_exactness_test.go 1e78f7fcaf38295bd1e923dbb7b0dbf30476393ebffc86273207f2d7e7789df4 requirements.txt 1f3a72bcaf3825d01a6fa6da0b0a781cb4028779181a498311e9c2de073e36fb module/testdata/vcn-v1/cases/desired-absent/expected/observed.oci.json 1f3a72bcaf3825d01a6fa6da0b0a781cb4028779181a498311e9c2de073e36fb module/testdata/vcn-v1/cases/field-absent/expected/observed.oci.json @@ -30,7 +32,6 @@ 247687949482cd6e8645802f2daaaa50d2b0fe546b5b66c97a887830ae6a9e17 module/oci_sign.go 256506d6120cd3ad29d63578dc2c4f8f1dffb8f087270d0a74dd5683deb107cc module/testdata/vcn-v1/cases/desired-absent-observed-present/expected/evidence.claims.json 256506d6120cd3ad29d63578dc2c4f8f1dffb8f087270d0a74dd5683deb107cc module/testdata/vcn-v1/cases/field-absent/expected/evidence.claims.json -2631dbec077e6263a54cf9e2a0389395819859ae0619d5a163e8bd54b8643bff module/m4a_helpers_test.go 2a1559feea3ff94f981c19b44d3e963cb3ff5632ebc7e17f3dace9ef52341624 module/plan_binding.go 2a6bc913a5c877b2b2dfb30f68d165950d9c881606819d6873047f1122c63abf docs/hu/architecture.yaml 2ab20175d0b7d0f2a7ebe960903a08dc7fe69620615f253ae1fa3e584747edaa pytest.ini @@ -55,7 +56,6 @@ 35bd42c0d55ea02ea9701070141dbb7ebc01d6b020e1cea9103bc5f0ec22c243 module/testdata/vcn-v1/cases/field-absent/oci/response.json 374a2c54d3fcd2b684d2a1699fe7e67c69dffa51e302001c13f55b1468c8c0c2 tests/test_tools/test_compiler.py 3766bf4bce6194763f838cc1f2aebff0801d4451956b8446916b17ecf846c2d7 abi.schema.yaml -38cc687d4b502af22a62ea96ac29a45e9a414fe72a4b0d2a584d4a859bd18ba5 module/plan_noop_exactness_test.go 395199128c561de3e991d635b3d93a2f2a8d7809de5ebe7195877ac37c2d92ba README.md 3afc5e1977e9258dd478d592606874b8fad4229f72306b15ef072c2b7fe67665 module/abi_negative_test.go 3c9bd79e75e97207cc669159b980e331ae8f75b36c0e9899b4a66f3deac0846d module/testdata/vcn-v1/cases/partial-read/expected/verdict.fields.json @@ -143,6 +143,7 @@ 9de6268f09ede92c5adcb82ceec4ecd66761ade6e6aa79131cfeb8cc9814f44d tools/wasm_assert_tests_passed.sh a03b3fccfc1f8eb7f76833fdff8a50ea84c80c039db87bc0e41109e96f64420b docs/en/concept/declarative_ecosystem_integration.md a1cba33d61cd932030481da78da553eb0f31b536a7c3879d5bdd9992c69d189a module/testdata/vcn-v1/cases/not-found/expected/observed.oci.json +a1e862a6a87ea57478aca53deaba38d92a70704a26c7b67f84ed0d8959b438c6 module/m4a_helpers_test.go a3f497092a2fe0fc41467edefff241687affff6f01adbbbf0dadbdefd791bd21 tools/compiler.py a44687b269fac17633c80d8e735cf3402d5f65fd0bb2c24e9996d0a89e134c94 docs/contracts/hu/envelope.md a4c522ffc80fc87ff4244ba3da8f19591d8206ed9acb4d1d7896ced9f75714a3 docs/design/specs/state-model.md @@ -173,7 +174,6 @@ c54659558693be5238ff020322eb00ca80ce7d14aea461ee1ae24361e80fe84f tools/releasel c55c74bb201c91330aa8bda11dd256fe35f84b3a3a0e24a1cebe3e487bd60135 requirements.in c637082ac035d4dda23ff27a31dfd7bd9a62437db24b53d48d585897fa1874a7 module/testdata/vcn-v1/not-planned.json c6919cec77cbf13916932f91cdc9b9d32d9290282c5d87244af7adc1a30d441a module/go.sum -c6f4ed120394d5d71b37e9b44293561cc76be2c7a8087d3facb12458c1b08805 module/m4a_gate_test.go c83bb77196b26e0f656d38b38736a488ff2aa316d995908bf9abade63fccdd67 tools/wasm_fresh_guest_test.sh ca7e4a9412ff28a5ca3e3fd9c759a62126564d82e8892b12b6efa1cbf11d5810 tools/oci-extract/client.go cb1301d5e401e05e2c14042cb1af909dc2bc819a636b5b4e1533f4c87ed48831 docs/design/specs/approval-and-execution-state.md @@ -184,7 +184,6 @@ cdc268dd275143f3cbad6b84078f397367c40951812143d227b5490cd007ce82 tools/infra.py d08117cca9ab07e9035ddd59f5e7cb0a610517f95b85542988a3222f08a015da module/testdata/instance-fixture.json d2c71865652ef4c4f9bed86eaeac6e5a63570e8677987b90a97cb756258ab234 feature-list.md d2dfadbd6532e7de6ae35af273fbdc446ffbb3e7f5b24d7092b3dea70ec2001b module/poll_contract_test.go -d3bce87b8745997eb0fb912dcd61c4ee8fd6d6596be6fec41a51649edcf32684 docs/design/specs/canonical-json.md d3ee577820563d1e062dae6243711e4467c2920e1001fad8c4933f5cd4a320be docs/contracts/hu/release-artifact.md d5c7049ae62583fb629ada0f600be689015ffcbaa5290982d989dbe260ff96c5 tools/oci-extract/testdata/compute_client.go d5daed86d55d8b22d307e8b4df9ab5af7cfa9c2647750d28c5344daeb40f92f8 module/testdata/vcn-v1/cases/conformant/intent.registry.json @@ -243,5 +242,6 @@ f75b14ade8b810dcd2f4b74008fc1bd5d6fd42bb3a44d3cd72d2c1f82e69ca91 tools/oci-extr fa13c93d96137cd60abaf523186ba2a0fa48ec28df52c55a49767cd58f88ef29 module/testdata/vcn-v1/cases/drift/expected/verdict.fields.json fb5779e0edb8a71595d9d8c81946bfb324b86066c6b94b73b036e3e110591b5c module/testdata/vcn-v1/cases/desired-absent/expected/verdict.fields.json fb885dd678928855a632f1411e364e0674409d8fa15da767ce07d036e2da824f tools/oci-extract/cmd/oci-sweep/main.go +fbe50f259dca8b38a1772df4d5e3f70509cd5293ec7944a08f424713479646c8 docs/design/specs/canonical-json.md fc893fc83e0ba0aac68d4fa7813ec56ac425fe385e4d896fd77532ee94a39509 tools/oci-extract/testdata/vcn.go fd1ca75aba965be594bceb3fe1ad0232750f0ba1a9232dbb5ed64eb280e8c60e docs/design/specs/provider-abi.md diff --git a/docs/design/specs/canonical-json.md b/docs/design/specs/canonical-json.md index 2a1a8c9..7413cf4 100644 --- a/docs/design/specs/canonical-json.md +++ b/docs/design/specs/canonical-json.md @@ -24,7 +24,7 @@ The input is one strict JSON text (RFC 8259). The output is deterministic: - **Whitespace** is dropped (only space, tab, CR and LF are whitespace on input). - **Objects**: members sorted by the **decoded key's UTF-8 bytes**; the keys are - compared after escapes are decoded (`"a"` is `"a"`). A **repeated key is an + compared after escapes are decoded (`"\u0061"` is `"a"`). A **repeated key is an error**, never merged. - **Arrays** keep their order. - **Numbers** are exact, with no floating point: the value is written as diff --git a/module/m4a_gate_test.go b/module/m4a_gate_test.go index ae045fc..36ef805 100644 --- a/module/m4a_gate_test.go +++ b/module/m4a_gate_test.go @@ -490,11 +490,14 @@ func TestEquivalentSpellingsOfDesiredAndObservedGiveOnePlanDigest(t *testing.T) {"plain", `{"displayName":"new","compartmentId":"ocid1.compartment..b"}`, `{"displayName":"old","compartmentId":"ocid1.compartment..a"}`}, {"key order", `{"compartmentId":"ocid1.compartment..b","displayName":"new"}`, `{"compartmentId":"ocid1.compartment..a","displayName":"old"}`}, {"whitespace", ` { "displayName" : "new" , "compartmentId" : "ocid1.compartment..b" } `, "{\n\t\"displayName\": \"old\",\n\t\"compartmentId\": \"ocid1.compartment..a\"\n}"}, - {"escapes", `{"displayName":"new","compartmentId":"ocid1.compartment..b"}`, `{"displayName":"old","compartmentId":"ocid1.compartment..a"}`}, + {"escapes", `{"displayName":"n` + backslash + `u0065w","compartmentId":"ocid1.compartment..b"}`, `{"displayName":"o` + backslash + `u006cd","compartmentId":"ocid1.compartment..a"}`}, } want := m4aPlan(t, bindingKind, spellings[0].desired, spellings[0].observed, b) for _, s := range spellings[1:] { t.Run(s.name, func(t *testing.T) { + if s.name == "escapes" && (!strings.Contains(s.desired, backslash+"u") || !strings.Contains(s.observed, backslash+"u")) { + t.Fatalf("test setup: the escapes spelling carries no u-escape (%q, %q): it would test identical text", s.desired, s.observed) + } got := m4aPlan(t, bindingKind, s.desired, s.observed, b) if got.PlanDigest != want.PlanDigest || got.ExecutionDigest != want.ExecutionDigest { t.Errorf("plan_digest %s, want %s: the same state spelled differently must give one digest", got.PlanDigest, want.PlanDigest) diff --git a/module/m4a_helpers_test.go b/module/m4a_helpers_test.go index 4da0fa4..42085d8 100644 --- a/module/m4a_helpers_test.go +++ b/module/m4a_helpers_test.go @@ -15,6 +15,11 @@ import ( const m4aHash = "abc123" +// backslash is spelled as a hex escape so that no editor or tool between this file and the +// compiler can rewrite a u-escape that a test builds on top of it (that happened once: the +// "escape spelling" cases of this package compared identical text). +const backslash = "\x5c" + func m4aPayload(id, data string) schemaPayload { return schemaPayload{SchemaID: id, SchemaVersion: "v0.1.0", SchemaHash: m4aHash, Encoding: encCanonicalJSON, Data: json.RawMessage(data)} } diff --git a/module/plan_noop_exactness_test.go b/module/plan_noop_exactness_test.go index 4dba931..2731758 100644 --- a/module/plan_noop_exactness_test.go +++ b/module/plan_noop_exactness_test.go @@ -53,7 +53,7 @@ func TestPlanStillCallsEquivalentJSONANoop(t *testing.T) { {"number spelling", `{"shapeConfig":{"ocpus":1},"displayName":"x"}`, `{"shapeConfig":{"ocpus":1.0},"displayName":"x"}`}, {"exponent spelling", `{"shapeConfig":{"ocpus":100},"displayName":"x"}`, `{"shapeConfig":{"ocpus":1e2},"displayName":"x"}`}, {"key order and whitespace", `{"shapeConfig":{"ocpus":2,"memoryInGBs":16},"displayName":"x"}`, ` { "displayName":"x", "shapeConfig":{ "memoryInGBs":16, "ocpus":2 } } `}, - {"escaped text", `{"displayName":"é"}`, "{\"displayName\":\"\xc3\xa9\"}"}, + {"escaped text", `{"displayName":"` + backslash + `u00e9"}`, "{\"displayName\":\"\xc3\xa9\"}"}, } { t.Run(c.name, func(t *testing.T) { res, plan := planInstance(t, c.desired, c.observed)