Skip to content

Commit d686aa0

Browse files
authored
Fix profile render when the README.md size is larger than 1024 bytes (#25270)
Backport #25131
1 parent 037366f commit d686aa0

File tree

6 files changed

+114
-10
lines changed

6 files changed

+114
-10
lines changed

modules/git/blob.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,18 @@ func (b *Blob) Name() string {
2020
return b.name
2121
}
2222

23-
// GetBlobContent Gets the content of the blob as raw text
24-
func (b *Blob) GetBlobContent() (string, error) {
23+
// GetBlobContent Gets the limited content of the blob as raw text
24+
func (b *Blob) GetBlobContent(limit int64) (string, error) {
25+
if limit <= 0 {
26+
return "", nil
27+
}
2528
dataRc, err := b.DataAsync()
2629
if err != nil {
2730
return "", err
2831
}
2932
defer dataRc.Close()
30-
buf := make([]byte, 1024)
31-
n, _ := util.ReadAtMost(dataRc, buf)
32-
buf = buf[:n]
33-
return string(buf), nil
33+
buf, err := util.ReadWithLimit(dataRc, int(limit))
34+
return string(buf), err
3435
}
3536

3637
// GetBlobLineCount gets line count of the blob

modules/util/io.go

+38-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
package util
55

66
import (
7+
"bytes"
78
"errors"
89
"io"
910
)
1011

1112
// ReadAtMost reads at most len(buf) bytes from r into buf.
1213
// It returns the number of bytes copied. n is only less than len(buf) if r provides fewer bytes.
13-
// If EOF occurs while reading, err will be nil.
14+
// If EOF or ErrUnexpectedEOF occurs while reading, err will be nil.
1415
func ReadAtMost(r io.Reader, buf []byte) (n int, err error) {
1516
n, err = io.ReadFull(r, buf)
1617
if err == io.EOF || err == io.ErrUnexpectedEOF {
@@ -19,6 +20,42 @@ func ReadAtMost(r io.Reader, buf []byte) (n int, err error) {
1920
return n, err
2021
}
2122

23+
// ReadWithLimit reads at most "limit" bytes from r into buf.
24+
// If EOF or ErrUnexpectedEOF occurs while reading, err will be nil.
25+
func ReadWithLimit(r io.Reader, n int) (buf []byte, err error) {
26+
return readWithLimit(r, 1024, n)
27+
}
28+
29+
func readWithLimit(r io.Reader, batch, limit int) ([]byte, error) {
30+
if limit <= batch {
31+
buf := make([]byte, limit)
32+
n, err := ReadAtMost(r, buf)
33+
if err != nil {
34+
return nil, err
35+
}
36+
return buf[:n], nil
37+
}
38+
res := bytes.NewBuffer(make([]byte, 0, batch))
39+
bufFix := make([]byte, batch)
40+
eof := false
41+
for res.Len() < limit && !eof {
42+
bufTmp := bufFix
43+
if res.Len()+batch > limit {
44+
bufTmp = bufFix[:limit-res.Len()]
45+
}
46+
n, err := io.ReadFull(r, bufTmp)
47+
if err == io.EOF || err == io.ErrUnexpectedEOF {
48+
eof = true
49+
} else if err != nil {
50+
return nil, err
51+
}
52+
if _, err = res.Write(bufTmp[:n]); err != nil {
53+
return nil, err
54+
}
55+
}
56+
return res.Bytes(), nil
57+
}
58+
2259
// ErrNotEmpty is an error reported when there is a non-empty reader
2360
var ErrNotEmpty = errors.New("not-empty")
2461

modules/util/io_test.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package util
5+
6+
import (
7+
"bytes"
8+
"errors"
9+
"testing"
10+
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
type readerWithError struct {
15+
buf *bytes.Buffer
16+
}
17+
18+
func (r *readerWithError) Read(p []byte) (n int, err error) {
19+
if r.buf.Len() < 2 {
20+
return 0, errors.New("test error")
21+
}
22+
return r.buf.Read(p)
23+
}
24+
25+
func TestReadWithLimit(t *testing.T) {
26+
bs := []byte("0123456789abcdef")
27+
28+
// normal test
29+
buf, err := readWithLimit(bytes.NewBuffer(bs), 5, 2)
30+
assert.NoError(t, err)
31+
assert.Equal(t, []byte("01"), buf)
32+
33+
buf, err = readWithLimit(bytes.NewBuffer(bs), 5, 5)
34+
assert.NoError(t, err)
35+
assert.Equal(t, []byte("01234"), buf)
36+
37+
buf, err = readWithLimit(bytes.NewBuffer(bs), 5, 6)
38+
assert.NoError(t, err)
39+
assert.Equal(t, []byte("012345"), buf)
40+
41+
buf, err = readWithLimit(bytes.NewBuffer(bs), 5, len(bs))
42+
assert.NoError(t, err)
43+
assert.Equal(t, []byte("0123456789abcdef"), buf)
44+
45+
buf, err = readWithLimit(bytes.NewBuffer(bs), 5, 100)
46+
assert.NoError(t, err)
47+
assert.Equal(t, []byte("0123456789abcdef"), buf)
48+
49+
// test with error
50+
buf, err = readWithLimit(&readerWithError{bytes.NewBuffer(bs)}, 5, 10)
51+
assert.NoError(t, err)
52+
assert.Equal(t, []byte("0123456789"), buf)
53+
54+
buf, err = readWithLimit(&readerWithError{bytes.NewBuffer(bs)}, 5, 100)
55+
assert.ErrorContains(t, err, "test error")
56+
assert.Empty(t, buf)
57+
58+
// test public function
59+
buf, err = ReadWithLimit(bytes.NewBuffer(bs), 2)
60+
assert.NoError(t, err)
61+
assert.Equal(t, []byte("01"), buf)
62+
63+
buf, err = ReadWithLimit(bytes.NewBuffer(bs), 9999999)
64+
assert.NoError(t, err)
65+
assert.Equal(t, []byte("0123456789abcdef"), buf)
66+
}

routers/web/user/profile.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func Profile(ctx *context.Context) {
107107
}
108108
blob, err := commit.GetBlobByPath("README.md")
109109
if err == nil {
110-
bytes, err := blob.GetBlobContent()
110+
bytes, err := blob.GetBlobContent(setting.UI.MaxDisplayFileSize)
111111
if err != nil {
112112
ctx.ServerError("GetBlobContent", err)
113113
return

services/repository/files/content.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
203203
} else if entry.IsLink() {
204204
contentsResponse.Type = string(ContentTypeLink)
205205
// The target of a symlink file is the content of the file
206-
targetFromContent, err := entry.Blob().GetBlobContent()
206+
targetFromContent, err := entry.Blob().GetBlobContent(1024)
207207
if err != nil {
208208
return nil, err
209209
}

tests/integration/api_packages_cargo_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) {
8888
blob, err := commit.GetBlobByPath(path)
8989
assert.NoError(t, err)
9090

91-
content, err := blob.GetBlobContent()
91+
content, err := blob.GetBlobContent(1024)
9292
assert.NoError(t, err)
9393

9494
return content

0 commit comments

Comments
 (0)