fork of indigo with slightly nicer lexgen

syntax: basic CID (string only) syntax

Changed files
+128
atproto
+48
atproto/syntax/cid.go
··· 1 + package syntax 2 + 3 + import ( 4 + "fmt" 5 + "regexp" 6 + "strings" 7 + ) 8 + 9 + // Represents a CIDv1 in string format, as would pass Lexicon syntax validation. 10 + // 11 + // You usually want to use the github.com/ipfs/go-cid package and type when working with CIDs ("Links") in atproto. This specific type (syntax.CID) is an informal/incomplete helper specifically for doing fast string verification or pass-through without parsing, re-serialization, or normalization. 12 + // 13 + // Always use [ParseCID] instead of wrapping strings directly, especially when working with network input. 14 + type CID string 15 + 16 + func ParseCID(raw string) (CID, error) { 17 + if len(raw) > 256 { 18 + return "", fmt.Errorf("CID is too long (256 chars max)") 19 + } 20 + if len(raw) < 8 { 21 + return "", fmt.Errorf("CID is too short (8 chars min)") 22 + } 23 + var cidRegex = regexp.MustCompile(`^[a-zA-Z0-9+=]{8,256}$`) 24 + if !cidRegex.MatchString(raw) { 25 + return "", fmt.Errorf("CID syntax didn't validate via regex") 26 + } 27 + if strings.HasPrefix(raw, "Qmb") { 28 + return "", fmt.Errorf("CIDv0 not allowed in this version of atproto") 29 + } 30 + return CID(raw), nil 31 + } 32 + 33 + func (c CID) String() string { 34 + return string(c) 35 + } 36 + 37 + func (c CID) MarshalText() ([]byte, error) { 38 + return []byte(c.String()), nil 39 + } 40 + 41 + func (c *CID) UnmarshalText(text []byte) error { 42 + cid, err := ParseCID(string(text)) 43 + if err != nil { 44 + return err 45 + } 46 + *c = cid 47 + return nil 48 + }
+50
atproto/syntax/cid_test.go
··· 1 + package syntax 2 + 3 + import ( 4 + "bufio" 5 + "fmt" 6 + "os" 7 + "testing" 8 + 9 + "github.com/stretchr/testify/assert" 10 + ) 11 + 12 + func TestInteropCIDsValid(t *testing.T) { 13 + assert := assert.New(t) 14 + file, err := os.Open("testdata/cid_syntax_valid.txt") 15 + assert.NoError(err) 16 + defer file.Close() 17 + scanner := bufio.NewScanner(file) 18 + for scanner.Scan() { 19 + line := scanner.Text() 20 + if len(line) == 0 || line[0] == '#' { 21 + continue 22 + } 23 + _, err := ParseCID(line) 24 + if err != nil { 25 + fmt.Println("GOOD: " + line) 26 + } 27 + assert.NoError(err) 28 + } 29 + assert.NoError(scanner.Err()) 30 + } 31 + 32 + func TestInteropCIDsInvalid(t *testing.T) { 33 + assert := assert.New(t) 34 + file, err := os.Open("testdata/cid_syntax_invalid.txt") 35 + assert.NoError(err) 36 + defer file.Close() 37 + scanner := bufio.NewScanner(file) 38 + for scanner.Scan() { 39 + line := scanner.Text() 40 + if len(line) == 0 || line[0] == '#' { 41 + continue 42 + } 43 + _, err := ParseCID(line) 44 + if err == nil { 45 + fmt.Println("BAD: " + line) 46 + } 47 + assert.Error(err) 48 + } 49 + assert.NoError(scanner.Err()) 50 + }
+16
atproto/syntax/testdata/cid_syntax_invalid.txt
··· 1 + example.com 2 + https://example.com 3 + cid:bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi 4 + . 5 + 12345 6 + 7 + # whitespace 8 + bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi 9 + bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi 10 + bafybe igdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi 11 + 12 + # old CIDv0 not supported 13 + QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR 14 + 15 + # https://github.com/ipfs-shipyard/is-ipfs/blob/master/test/test-cid.spec.ts 16 + noop
+14
atproto/syntax/testdata/cid_syntax_valid.txt
··· 1 + 2 + # examples from https://docs.ipfs.tech/concepts/content-addressing 3 + bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi 4 + 5 + # https://github.com/ipfs-shipyard/is-ipfs/blob/master/test/test-cid.spec.ts 6 + zdj7WWeQ43G6JJvLWQWZpyHuAMq6uYWRjkBXFad11vE2LHhQ7 7 + bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va 8 + 9 + # more contrived examples 10 + mBcDxtdWx0aWhhc2g+ 11 + z7x3CtScH765HvShXT 12 + zdj7WhuEjrB52m1BisYCtmjH1hSKa7yZ3jEZ9JcXaFRD51wVz 13 + 7134036155352661643226414134664076 14 + f017012202c5f688262e0ece8569aa6f94d60aad55ca8d9d83734e4a7430d0cff6588ec2b