From c2d883c7c58a3bd64d799dd000fe7254e450a4e5 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sun, 7 Jun 2026 11:01:26 +0000 Subject: object/tree/mode: Initialize --- object/tree/mode/parse.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 object/tree/mode/parse.go (limited to 'object/tree/mode/parse.go') diff --git a/object/tree/mode/parse.go b/object/tree/mode/parse.go new file mode 100644 index 00000000..7839a89a --- /dev/null +++ b/object/tree/mode/parse.go @@ -0,0 +1,43 @@ +package mode + +import ( + "errors" + "fmt" +) + +// ErrInvalidMode indicates a malformed or unsupported tree entry mode. +var ErrInvalidMode = errors.New("object/tree/mode: invalid mode") + +// Parse decodes a canonical octal tree entry mode. +// +// It accepts only the modes Git itself writes +// and rejects malformed, unsupported, and zero-padded encodings. +func Parse(raw []byte) (Mode, error) { + if len(raw) == 0 { + return 0, fmt.Errorf("%w: empty mode", ErrInvalidMode) + } + + if raw[0] == '0' { + return 0, fmt.Errorf("%w: zero-padded mode %q", ErrInvalidMode, raw) + } + + if len(raw) > maxModeDigits { + return 0, fmt.Errorf("%w: mode %q too long", ErrInvalidMode, raw) + } + + var mode Mode + + for _, c := range raw { + if c < '0' || c > '7' { + return 0, fmt.Errorf("%w: non-octal byte in mode %q", ErrInvalidMode, raw) + } + + mode = mode<<3 | Mode(c-'0') + } + + if !mode.IsValid() { + return 0, fmt.Errorf("%w: unsupported mode %q", ErrInvalidMode, raw) + } + + return mode, nil +} -- cgit v1.3.1-10-gc9f91