Skip to content

Edge-sync spoke IDs can still collide through case folding and Unicode normalization #740

Description

@xe-nvdk

Follow-up from #737, found while writing its regression test.

#737 closed the .. fold. The same class remains open for two other many-to-one mappings the filesystem applies rather than Arc:

Arc ships a darwin-arm64 binary through the Homebrew tap (release-build.yml:353), so macOS is a supported platform to run and develop on. CI is ubuntu-latest only (ci.yml:29), so nothing catches it.

The precondition is the same as #737: an administrator has to register the colliding ID, since registration is admin-only and there is no self-registration. No advisory.

TestSpokeNamespacesAreInjective in internal/edgesync/receive_test.go deliberately excludes ROCKET_01 from its candidate list with a comment pointing here, because including it would pass on Linux CI and fail on a macOS dev machine.

Why it was not folded into #737

Rejecting non-lowercase or non-NFC IDs would refuse identifiers that are legitimate today, so it breaks existing deployments in a way the .. fix does not: .. in a spoke ID is always pathological, mixed case is not. That needs a deprecation path rather than a validator line.

Options

  1. Reject non-lowercase and non-NFC IDs at registration only, leaving existing rows working, and warn about the ones already stored (Registry.InvalidStoredIDs added in Edge-sync spoke IDs containing an embedded .. collide with another spoke's local namespace #737 is the hook).
  2. Normalize on the way in and store the canonical form, which changes what registry.List() returns and therefore what receivedNamespaces in cmd/arc/main.go matches against on disk. Needs care.
  3. Make the invariant structural at the storage boundary so the namespace encoding is injective regardless of identifier spelling. See the related sanitizePath issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions