carlos / platform Public

settings-5 task 8: fix round 2 (NUL in an account is invalid in SQL too)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 8837f20a164c80e35ba7d3ec69f7716bb954c57b parent 3e24809
2 files changed, +11 −4
  • internal/registry/registry.go +6 −3
  • internal/registry/updatesettings_test.go +5 −1
diff --git a/internal/registry/registry.go b/internal/registry/registry.go
index 3dafe927e..c838453b4 100644
--- a/internal/registry/registry.go
+++ b/internal/registry/registry.go
@@ -1119,10 +1119,13 @@ func EffectiveAccount(account string) string {
// effectiveAccountSQL is EffectiveAccount as a SQLite expression over col.
// controlname.ValidAccount is ^[a-z]{3,16}$: three to sixteen characters,
-// none outside a-z. TestEffectiveAccountSQLIsEffectiveAccount pins the two
-// together.
+// none outside a-z. SQLite's length and GLOB both stop at an embedded NUL,
+// so the NUL is rejected explicitly (instr compares the whole value);
+// without that "abc\x00x" would read as the valid "abc" while Go rejects it.
+// TestEffectiveAccountSQLIsEffectiveAccount pins the two together.
func effectiveAccountSQL(col string) string {
- return `(CASE WHEN length(` + col + `) BETWEEN 3 AND 16 AND ` + col + ` NOT GLOB '*[^a-z]*' THEN ` + col +
+ return `(CASE WHEN length(` + col + `) BETWEEN 3 AND 16 AND instr(` + col + `, char(0)) = 0 AND ` + col +
+ ` NOT GLOB '*[^a-z]*' THEN ` + col +
` ELSE '` + opsAccount + `' END)`
}
diff --git a/internal/registry/updatesettings_test.go b/internal/registry/updatesettings_test.go
index 17fd5ad82..0dcc695d7 100644
--- a/internal/registry/updatesettings_test.go
+++ b/internal/registry/updatesettings_test.go
@@ -119,6 +119,9 @@ func TestAnEquivalentAccountSpellingIsTheSameTenant(t *testing.T) {
state := `{"known":true,"replica":true}`
for _, tc := range []struct{ from, to string }{
{"", "bab"}, {"bab", ""}, {"", ""}, {"NOT-VALID", "bab"}, {"bab", "x"},
+ // Astra r5 N1: an embedded NUL is invalid (SQLite's length and
+ // GLOB stop at it), so these are the ops account too.
+ {"abc\x00x", "bab"}, {"bab", "abc\x00x"}, {"abc\x00x", ""}, {"abc\x00", "bab"}, {"\x00", "bab"}, {"abc\x00x", "abc\x00y"},
} {
if err := reg.Upsert(Route{Host: host, Kind: "instance", Account: tc.from, App: "km", UpdateSettings: settings, BuildState: state}); err != nil {
t.Fatal(err)
@@ -153,7 +156,8 @@ func TestEffectiveAccountSQLIsEffectiveAccount(t *testing.T) {
t.Fatal(err)
}
for _, a := range []string{"", "bab", "bes", "abc", "ab", "a", "abcdefghijklmnop", "abcdefghijklmnopq",
- "Abc", "ABC", "ab1", "a-b", "a_b", "a b", " abc", "abc ", "abc\n", "\u00e1bc", "ab\u00e1", "ab]", "ab^", "ab*", "ab?", "ab["} {
+ "Abc", "ABC", "ab1", "a-b", "a_b", "a b", " abc", "abc ", "abc\n", "\u00e1bc", "ab\u00e1", "ab]", "ab^", "ab*", "ab?", "ab[",
+ "abc\x00x", "abc\x00", "\x00abc", "\x00", "abc\x00\x00", "ab\x00", "abcdefghijklmnop\x00x"} {
var got string
if err := reg.sql.QueryRow(`SELECT `+effectiveAccountSQL("?1"), a).Scan(&got); err != nil {
t.Fatal(err)