48 lines
1.6 KiB
Go
48 lines
1.6 KiB
Go
package lang
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestEmbeddedVersionMutation is the П0 acceptance test (D39.60 §6.1, "bytes ARE version" for the embed
|
|
// plane): a byte edit of an embedded data file MUST move EmbeddedVersion — so, once it is folded into the
|
|
// snapshot, an edit is a loud --resnapshot, never a silent verdict/wire change. It also pins the format and
|
|
// reproducibility (the same bytes always hash the same).
|
|
func TestEmbeddedVersionMutation(t *testing.T) {
|
|
got := EmbeddedVersion()
|
|
if !strings.HasPrefix(got, embedAlgoVersion+"-") {
|
|
t.Fatalf("EmbeddedVersion() = %q, want %s-<hash>", got, embedAlgoVersion)
|
|
}
|
|
|
|
files := embeddedDataFiles()
|
|
if len(files) == 0 {
|
|
t.Fatal("no embedded data files")
|
|
}
|
|
if base := hashEmbeddedFiles(files); base != got {
|
|
t.Fatalf("EmbeddedVersion not reproducible from embeddedDataFiles(): %s != %s", base, got)
|
|
}
|
|
|
|
// Mutate ONE byte of a verdict-bearing file (target-ru.txt drives the sanitizer) and a wire-bearing file
|
|
// (injection.txt rides the request) — each must diverge the hash on its own.
|
|
for _, target := range []string{"target-ru.txt", "injection.txt"} {
|
|
mutated := make([]embeddedFile, len(files))
|
|
copy(mutated, files)
|
|
var found bool
|
|
for i := range mutated {
|
|
if mutated[i].name == target {
|
|
b := append([]byte(nil), mutated[i].data...)
|
|
b[len(b)/2] ^= 0x01 // flip a content byte
|
|
mutated[i].data = b
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatalf("%s is not embedded", target)
|
|
}
|
|
if mut := hashEmbeddedFiles(mutated); mut == got {
|
|
t.Errorf("a byte edit of %s did NOT move EmbeddedVersion (%s) — the embed plane would drift silently", target, mut)
|
|
}
|
|
}
|
|
}
|