@@ -5,8 +5,6 @@ package markup
5
5
6
6
import (
7
7
"bufio"
8
- "bytes"
9
- "fmt"
10
8
"html"
11
9
"io"
12
10
"regexp"
@@ -15,6 +13,8 @@ import (
15
13
"code.gitea.io/gitea/modules/csv"
16
14
"code.gitea.io/gitea/modules/markup"
17
15
"code.gitea.io/gitea/modules/setting"
16
+ "code.gitea.io/gitea/modules/translation"
17
+ "code.gitea.io/gitea/modules/util"
18
18
)
19
19
20
20
func init () {
@@ -81,86 +81,38 @@ func writeField(w io.Writer, element, class, field string) error {
81
81
func (r Renderer ) Render (ctx * markup.RenderContext , input io.Reader , output io.Writer ) error {
82
82
tmpBlock := bufio .NewWriter (output )
83
83
maxSize := setting .UI .CSV .MaxFileSize
84
+ maxRows := setting .UI .CSV .MaxRows
84
85
85
- if maxSize = = 0 {
86
- return r . tableRender ( ctx , input , tmpBlock )
86
+ if maxSize ! = 0 {
87
+ input = io . LimitReader ( input , maxSize + 1 )
87
88
}
88
89
89
- rawBytes , err := io .ReadAll (io .LimitReader (input , maxSize + 1 ))
90
- if err != nil {
91
- return err
92
- }
93
-
94
- if int64 (len (rawBytes )) <= maxSize {
95
- return r .tableRender (ctx , bytes .NewReader (rawBytes ), tmpBlock )
96
- }
97
- return r .fallbackRender (io .MultiReader (bytes .NewReader (rawBytes ), input ), tmpBlock )
98
- }
99
-
100
- func (Renderer ) fallbackRender (input io.Reader , tmpBlock * bufio.Writer ) error {
101
- _ , err := tmpBlock .WriteString ("<pre>" )
102
- if err != nil {
103
- return err
104
- }
105
-
106
- scan := bufio .NewScanner (input )
107
- scan .Split (bufio .ScanRunes )
108
- for scan .Scan () {
109
- switch scan .Text () {
110
- case `&` :
111
- _ , err = tmpBlock .WriteString ("&" )
112
- case `'` :
113
- _ , err = tmpBlock .WriteString ("'" ) // "'" is shorter than "'" and apos was not in HTML until HTML5.
114
- case `<` :
115
- _ , err = tmpBlock .WriteString ("<" )
116
- case `>` :
117
- _ , err = tmpBlock .WriteString (">" )
118
- case `"` :
119
- _ , err = tmpBlock .WriteString (""" ) // """ is shorter than """.
120
- default :
121
- _ , err = tmpBlock .Write (scan .Bytes ())
122
- }
123
- if err != nil {
124
- return err
125
- }
126
- }
127
- if err = scan .Err (); err != nil {
128
- return fmt .Errorf ("fallbackRender scan: %w" , err )
129
- }
130
-
131
- _ , err = tmpBlock .WriteString ("</pre>" )
132
- if err != nil {
133
- return err
134
- }
135
- return tmpBlock .Flush ()
136
- }
137
-
138
- func (Renderer ) tableRender (ctx * markup.RenderContext , input io.Reader , tmpBlock * bufio.Writer ) error {
139
90
rd , err := csv .CreateReaderAndDetermineDelimiter (ctx , input )
140
91
if err != nil {
141
92
return err
142
93
}
143
-
144
94
if _ , err := tmpBlock .WriteString (`<table class="data-table">` ); err != nil {
145
95
return err
146
96
}
147
- row := 1
97
+
98
+ row := 0
148
99
for {
149
100
fields , err := rd .Read ()
150
- if err == io .EOF {
101
+ if err == io .EOF || ( row >= maxRows && maxRows != 0 ) {
151
102
break
152
103
}
153
104
if err != nil {
154
105
continue
155
106
}
107
+
156
108
if _ , err := tmpBlock .WriteString ("<tr>" ); err != nil {
157
109
return err
158
110
}
159
111
element := "td"
160
- if row == 1 {
112
+ if row == 0 {
161
113
element = "th"
162
114
}
163
- if err := writeField (tmpBlock , element , "line-num" , strconv .Itoa (row )); err != nil {
115
+ if err := writeField (tmpBlock , element , "line-num" , strconv .Itoa (row + 1 )); err != nil {
164
116
return err
165
117
}
166
118
for _ , field := range fields {
@@ -174,8 +126,32 @@ func (Renderer) tableRender(ctx *markup.RenderContext, input io.Reader, tmpBlock
174
126
175
127
row ++
176
128
}
129
+
177
130
if _ , err = tmpBlock .WriteString ("</table>" ); err != nil {
178
131
return err
179
132
}
133
+
134
+ // Check if maxRows or maxSize is reached, and if true, warn.
135
+ if (row >= maxRows && maxRows != 0 ) || (rd .InputOffset () >= maxSize && maxSize != 0 ) {
136
+ warn := `<table class="data-table"><tr><td>`
137
+ rawLink := ` <a href="` + ctx .Links .RawLink () + `/` + util .PathEscapeSegments (ctx .RelativePath ) + `">`
138
+
139
+ // Try to get the user translation
140
+ if locale , ok := ctx .Ctx .Value (translation .ContextKey ).(translation.Locale ); ok {
141
+ warn += locale .TrString ("repo.file_too_large" )
142
+ rawLink += locale .TrString ("repo.file_view_raw" )
143
+ } else {
144
+ warn += "The file is too large to be shown."
145
+ rawLink += "View Raw"
146
+ }
147
+
148
+ warn += rawLink + `</a></td></tr></table>`
149
+
150
+ // Write the HTML string to the output
151
+ if _ , err := tmpBlock .WriteString (warn ); err != nil {
152
+ return err
153
+ }
154
+ }
155
+
180
156
return tmpBlock .Flush ()
181
157
}
0 commit comments