diff options
| author | 2026-03-26 09:19:01 +0000 | |
|---|---|---|
| committer | 2026-03-26 09:19:01 +0000 | |
| commit | 929b8cc620abca70b3444b09be5249f6c6cb7812 (patch) | |
| tree | 29b1edba8f597d09a2a51a6b2c901389cc40e242 /ref/name/component.go | |
| parent | format: Move commitgraph and packfile here (diff) | |
| signature | No signature | |
ref/name: Rename from ref/refname
Diffstat (limited to 'ref/name/component.go')
| -rw-r--r-- | ref/name/component.go | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/ref/name/component.go b/ref/name/component.go new file mode 100644 index 00000000..f5adba46 --- /dev/null +++ b/ref/name/component.go @@ -0,0 +1,88 @@ +package refname + +import "strings" + +func checkRefnameComponent(name string, flags *int, sanitized *strings.Builder, fullName string) (int, error) { + var last byte + + componentStart := sanitizedLen(sanitized) + + for i := range len(name) { + ch := name[i] + disp := refnameDisposition(ch) + + if sanitized != nil && disp != 1 { + sanitized.WriteByte(ch) + } + + switch disp { + case 1: + goto out + case 2: + if last == '.' { + if sanitized != nil { + truncateBuilder(sanitized, sanitized.Len()-1) + } else { + return 0, &NameError{Name: fullName, Reason: "name contains '..'"} + } + } + case 3: + if last == '@' { + if sanitized != nil { + overwriteLastByte(sanitized, '-') + } else { + return 0, &NameError{Name: fullName, Reason: "name contains '@{'"} + } + } + case 4: + if sanitized != nil { + overwriteLastByte(sanitized, '-') + } else { + return 0, &NameError{Name: fullName, Reason: "name contains one forbidden character"} + } + case 5: + if *flags&refnameRefspecPattern == 0 { + if sanitized != nil { + overwriteLastByte(sanitized, '-') + } else { + return 0, &NameError{Name: fullName, Reason: "name contains '*'"} + } + } + + *flags &^= refnameRefspecPattern + } + + last = ch + } + +out: + componentLen := strings.IndexByte(name, '/') + + if componentLen < 0 { + componentLen = len(name) + } + + if componentLen == 0 { + return 0, nil + } + + if name[0] == '.' { + if sanitized != nil { + overwriteBuilderAt(sanitized, componentStart, '-') + } else { + return 0, &NameError{Name: fullName, Reason: "component starts with '.'"} + } + } + + if componentLen >= len(lockSuffix) && name[componentLen-len(lockSuffix):componentLen] == lockSuffix { + if sanitized == nil { + return 0, &NameError{Name: fullName, Reason: "component ends with .lock"} + } + + for strings.HasSuffix(sanitized.String(), lockSuffix) { + truncateBuilder(sanitized, sanitized.Len()-len(lockSuffix)) + } + } + + return componentLen, nil +} |
