relay: expiry field is digits only (review fix)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2 files changed,
+7
−2
internal/relay/keys.go+5 −1internal/relay/keys_test.go+2 −1
diff --git a/internal/relay/keys.go b/internal/relay/keys.go| index 6e385edec..81a881251 100644 |
| --- a/internal/relay/keys.go |
| +++ b/internal/relay/keys.go |
| @@ -22,6 +22,7 @@ const ( |
| ) |
| var ( |
| + expiryRe = regexp.MustCompile(`^[0-9]+$`) |
| accountRe = regexp.MustCompile(`^[a-z0-9]+$`) |
| appRe = regexp.MustCompile(`^[a-z][a-z0-9-]{0,31}$`) |
| incarnationRe = regexp.MustCompile(`^[0-9a-f]{16}$`) |
| @@ -64,8 +65,11 @@ func ParseUsername(s string) (Username, error) { |
| if len(f) != 5 { |
| return Username{}, fmt.Errorf("relay: username has %d fields, want 5", len(f)) |
| } |
| + if !expiryRe.MatchString(f[0]) { |
| + return Username{}, fmt.Errorf("relay: bad expiry %q", f[0]) |
| + } |
| exp, err := strconv.ParseInt(f[0], 10, 64) |
| - if err != nil || exp < 0 { |
| + if err != nil { |
| return Username{}, fmt.Errorf("relay: bad expiry %q", f[0]) |
| } |
| switch { |
diff --git a/internal/relay/keys_test.go b/internal/relay/keys_test.go| index ab5e1cc3e..40dfc8a63 100644 |
| --- a/internal/relay/keys_test.go |
| +++ b/internal/relay/keys_test.go |
| @@ -9,7 +9,8 @@ func TestParseUsername(t *testing.T) { |
| } |
| for _, bad := range []string{"", "1:2:3:4", "1:2:3:4:5:6", "x:abc:meet:0123456789abcdef:k1", |
| "1900000000:ABC:meet:0123456789abcdef:k1", "1900000000:abc:9meet:0123456789abcdef:k1", |
| - "1900000000:abc:meet:short:k1", "1900000000:abc:meet:0123456789abcdef:K1"} { |
| + "1900000000:abc:meet:short:k1", "1900000000:abc:meet:0123456789abcdef:K1", |
| + "+1900000000:abc:meet:0123456789abcdef:k1"} { |
| if _, err := ParseUsername(bad); err == nil { |
| t.Errorf("ParseUsername(%q) accepted", bad) |
| } |