1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2025-08-02 16:35:19 +02:00

git/TreeEntry: LinkTarget simplification (#8323)

See #8222 for context.

This PR removes a call to `Blob.GetBlobContent` and `Blob.DataAsync` and unifies symlink resolution:
- length was unlimited in one case
- length was truncated to 1024 chars in the other case

Now it is hard-limited to 4096 chars (ie error if larger), which is a length which seems appropriate according to https://stackoverflow.com/a/22575737.

### Tests

- Tests are already present in `tests/integration/repo_test.go:972`: `TestRepoFollowSymlink` (it caught a cap/len stupid mistake).
- [x] I did not document these changes and I do not expect someone else to do it.
- [x] I do not want this change to show in the release notes.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8323
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: oliverpool <git@olivier.pfad.fr>
Co-committed-by: oliverpool <git@olivier.pfad.fr>
This commit is contained in:
oliverpool 2025-06-27 23:10:09 +02:00 committed by Earl Warren
parent 6b27fa66b9
commit 225a0f7026
2 changed files with 25 additions and 20 deletions

View file

@ -116,32 +116,37 @@ func (te *TreeEntry) Type() string {
}
}
// LinkTarget returns the target of the symlink as string.
func (te *TreeEntry) LinkTarget() (string, error) {
if !te.IsLink() {
return "", ErrBadLink{te.Name(), "not a symlink"}
}
const symlinkLimit = 4096 // according to git config core.longpaths https://stackoverflow.com/a/22575737
blob := te.Blob()
if blob.Size() > symlinkLimit {
return "", ErrBadLink{te.Name(), "symlink too large"}
}
rc, size, err := blob.NewTruncatedReader(symlinkLimit)
if err != nil {
return "", err
}
defer rc.Close()
buf := make([]byte, int(size))
_, err = io.ReadFull(rc, buf)
return string(buf), err
}
// FollowLink returns the entry pointed to by a symlink
func (te *TreeEntry) FollowLink() (*TreeEntry, string, error) {
if !te.IsLink() {
return nil, "", ErrBadLink{te.Name(), "not a symlink"}
}
// read the link
r, err := te.Blob().DataAsync()
lnk, err := te.LinkTarget()
if err != nil {
return nil, "", err
}
closed := false
defer func() {
if !closed {
_ = r.Close()
}
}()
buf := make([]byte, te.Size())
_, err = io.ReadFull(r, buf)
if err != nil {
return nil, "", err
}
_ = r.Close()
closed = true
lnk := string(buf)
t := te.ptree
// traverse up directories