package launchctx import ( "bytes" "crypto/sha256" "encoding/hex" "encoding/json" "io" "os" "strings" "testing" ) func launchFixture(t *testing.T) ([]byte, LaunchContext) { t.Helper() raw, err := os.ReadFile("testdata/launch-v2.json") if err != nil { t.Fatal(err) } c, err := DecodeLaunch(raw) if err != nil { t.Fatal(err) } return raw, c } func TestLaunchExactIntegersAndIndependentCheckpointVector(t *testing.T) { _, c := launchFixture(t) if c.DatabaseDevice != ^uint64(0) || c.DatabaseInode != 9007199254740993 || c.GuardGeneration != 9223372036854775807 { t.Fatal("integer precision lost") } raw, err := EncodeLaunch(c) if err != nil { t.Fatal(err) } again, err := ReadLaunch(bytes.NewReader(raw)) if err != nil || again.DatabaseDevice != c.DatabaseDevice || again.DatabaseInode != c.DatabaseInode { t.Fatal("round trip lost identity", err) } binding, err := os.ReadFile("testdata/launch-v2-binding.json") if err != nil { t.Fatal(err) } if !bytes.Contains(binding, []byte(`18446744073709551615`)) || !bytes.Contains(binding, []byte(`\u003chome\u003e\u0026`)) { t.Fatal("independent vector lacks precision/escaping cases") } if !bytes.Equal(binding, c.checkpointBytes()) { t.Fatal("Go binding differs from independent Python vector") } digest := sha256.Sum256(binding) if hex.EncodeToString(digest[:]) != c.ClosedCheckpoint.EvidenceSHA256 { t.Fatal("independent vector digest mismatch") } c.Version = 1 c.ExecutionKind = "" c.OperationID = "" c.ExpectedStateSHA256 = "" c.ClosedCheckpoint = nil raw, err = EncodeLaunch(c) if err != nil { t.Fatal(err) } if _, err := DecodeLaunch(raw); err != nil { t.Fatal(err) } c.ExecutionKind = "compatibility-check" if _, err := EncodeLaunch(c); err == nil { t.Fatal("v1 accepted checker fields") } } func TestLaunchRefusesEachMissingOrAmbiguousField(t *testing.T) { raw, _ := launchFixture(t) var fields map[string]json.RawMessage if err := json.Unmarshal(raw, &fields); err != nil { t.Fatal(err) } for key := range fields { t.Run(key, func(t *testing.T) { var f map[string]json.RawMessage json.Unmarshal(raw, &f) delete(f, key) bad, _ := json.Marshal(f) if _, err := DecodeLaunch(bad); err == nil { t.Fatal("missing field accepted") } f[strings.ToUpper(key)] = fields[key] bad, _ = json.Marshal(f) if _, err := DecodeLaunch(bad); err == nil { t.Fatal("case alias accepted") } f[key] = json.RawMessage("null") delete(f, strings.ToUpper(key)) bad, _ = json.Marshal(f) if _, err := DecodeLaunch(bad); err == nil { t.Fatal("null accepted") } }) } for _, bad := range [][]byte{append(append([]byte{}, raw...), []byte(` {}`)...), append([]byte(`{"version":2,`), bytes.TrimSpace(raw)[1:]...), bytes.Replace(raw, []byte(`"database_inode": 9007199254740993`), []byte(`"database_inode": 18446744073709551616`), 1), bytes.Replace(raw, []byte(`"guard_generation": 9223372036854775807`), []byte(`"guard_generation": 1e3`), 1), bytes.Replace(raw, []byte(`"database_inode": 9007199254740993`), []byte(`"database_inode": 1.0`), 1), bytes.Replace(raw, []byte(`"version": 2`), []byte(`"version": 2.0`), 1), bytes.Replace(raw, []byte(`"main_length": 268435456`), []byte(`"main_length": 268435457`), 1)} { if _, err := DecodeLaunch(bad); err == nil { t.Fatalf("malformed context accepted: %s", bad) } } } func TestLaunchCheckpointCannotBeTransplanted(t *testing.T) { _, c := launchFixture(t) raw, _ := EncodeLaunch(c) var fields map[string]json.RawMessage json.Unmarshal(raw, &fields) for key := range fields { if key == "closed_checkpoint" || key == "version" || key == "execution_kind" { continue } t.Run(key, func(t *testing.T) { var f map[string]json.RawMessage json.Unmarshal(raw, &f) var value any switch key { case "account": value = "abc" case "app": value = "docs" case "host": value = "other.bds.oncarlos.com" case "request_id", "attempt_id", "operation_id": value = strings.Repeat("A", 43) case "database_path": value = "/other/home.db" case "execution_deadline": value = "2026-09-11T21:00:00Z" case "guard_generation", "database_device", "database_inode": value = 2 default: value = strings.Repeat("a", 64) } f[key], _ = json.Marshal(value) bad, _ := json.Marshal(f) if _, err := DecodeLaunch(bad); err == nil { t.Fatal("changed valid binding accepted with old evidence") } var changed LaunchContext json.Unmarshal(bad, &changed) changed.ClosedCheckpoint.EvidenceSHA256 = changed.checkpointDigest() if _, err := EncodeLaunch(changed); err != nil { t.Fatal("mutation was not valid independent of its evidence", err) } }) } for _, mutate := range []func(*ClosedCheckpoint){func(p *ClosedCheckpoint) { p.PreparationID = strings.Repeat("A", 43) }, func(p *ClosedCheckpoint) { p.MainLength-- }, func(p *ClosedCheckpoint) { p.MainSHA256 = strings.Repeat("a", 64) }, func(p *ClosedCheckpoint) { p.CompletedAt = "2026-09-11T19:59:58Z" }} { _, v := launchFixture(t) mutate(v.ClosedCheckpoint) b, _ := json.Marshal(v) if _, err := DecodeLaunch(b); err == nil { t.Fatal("changed preparation accepted") } } } func TestLaunchSizeUTF8AndSurrogates(t *testing.T) { _, c := launchFixture(t) c.Version = 1 c.ExecutionKind = "" c.OperationID = "" c.ExpectedStateSHA256 = "" c.ClosedCheckpoint = nil raw, err := EncodeLaunch(c) if err != nil { t.Fatal(err) } exact := append(bytes.Repeat([]byte(" "), MaxLaunchBytes-len(raw)), raw...) if _, err := DecodeLaunch(exact); err != nil { t.Fatal("exact bound refused", err) } r := bytes.NewReader(append(exact, []byte("xx")...)) if _, err := ReadLaunch(r); err == nil || r.Len() != 1 { t.Fatal("overflow bound", err, r.Len()) } for _, path := range []string{`"/bad\ud800"`, `"/bad\udc00"`, `"/bad\ud800\u0001"`, `"/bad` + string([]byte{0xff}) + `"`} { oldPath, _ := json.Marshal(c.DatabasePath) bad := bytes.Replace(raw, oldPath, []byte(path), 1) if bytes.Equal(bad, raw) { t.Fatal("mutation missed path") } if _, err := DecodeLaunch(bad); err == nil { t.Fatal("invalid string accepted") } } c.DatabasePath = "/valid/😀/�/quoted\".db" raw, err = EncodeLaunch(c) if err != nil { t.Fatal(err) } raw = bytes.ReplaceAll(raw, []byte("😀"), []byte(`\ud83d\ude00`)) if _, err := DecodeLaunch(raw); err != nil { t.Fatal("valid surrogate pair refused", err) } if _, err := ReadLaunch(io.MultiReader(bytes.NewReader(raw), errReader{})); err == nil { t.Fatal("read error accepted") } } type errReader struct{} func (errReader) Read([]byte) (int, error) { return 0, io.ErrUnexpectedEOF } func TestNestedLaunchFieldsAreClosed(t *testing.T) { raw, _ := launchFixture(t) var top, fields map[string]json.RawMessage json.Unmarshal(raw, &top) original := top["closed_checkpoint"] json.Unmarshal(original, &fields) refuse := func(b json.RawMessage) { t.Helper() top["closed_checkpoint"] = b bad, _ := json.Marshal(top) if _, err := DecodeLaunch(bad); err == nil { t.Fatal("ambiguous checkpoint accepted") } } for key, value := range fields { t.Run(key, func(t *testing.T) { var f map[string]json.RawMessage json.Unmarshal(original, &f) delete(f, key) bad, _ := json.Marshal(f) refuse(bad) f[strings.ToUpper(key)] = value bad, _ = json.Marshal(f) refuse(bad) delete(f, strings.ToUpper(key)) f[key] = json.RawMessage("null") bad, _ = json.Marshal(f) refuse(bad) prefix, _ := json.Marshal(key) dup := append(append(append([]byte{'{'}, prefix...), ':'), value...) dup = append(dup, ',') dup = append(dup, bytes.TrimSpace(original)[1:]...) refuse(dup) }) } var f map[string]json.RawMessage json.Unmarshal(original, &f) f["extra"] = json.RawMessage("1") bad, _ := json.Marshal(f) refuse(bad) } func TestLaunchNumericAndTimestampLexicalForms(t *testing.T) { raw, c := launchFixture(t) for _, key := range []string{"version", "guard_generation", "database_device", "database_inode"} { for _, value := range []string{"0", "-0", "-1", "1.0", "1e0", "18446744073709551616"} { var f map[string]json.RawMessage json.Unmarshal(raw, &f) f[key] = json.RawMessage(value) bad, _ := json.Marshal(f) if _, err := DecodeLaunch(bad); err == nil { t.Fatal("noncanonical integer accepted", key, value) } } } for _, stamp := range []string{"2026-09-11T20:00:00+00:00", "2026-09-11T20:00:00.120Z", "2026-09-11t20:00:00Z", "2026-09-11T20:00:00z"} { v := c v.ExecutionDeadline = stamp v.ClosedCheckpoint = &ClosedCheckpoint{} *v.ClosedCheckpoint = *c.ClosedCheckpoint v.ClosedCheckpoint.EvidenceSHA256 = v.checkpointDigest() if _, err := EncodeLaunch(v); err == nil { t.Fatal("noncanonical timestamp accepted", stamp) } } c.ClosedCheckpoint.CompletedAt = c.ExecutionDeadline c.ClosedCheckpoint.EvidenceSHA256 = c.checkpointDigest() if _, err := EncodeLaunch(c); err != nil { t.Fatal("equal completion/deadline refused", err) } }