@@ -77,29 +77,62 @@ func writeField(w io.Writer, element, class, field string) error {
7777}
7878
7979// Render implements markup.Renderer 
80- func  (Renderer ) Render (ctx  * markup.RenderContext , input  io.Reader , output  io.Writer ) error  {
80+ func  (r   Renderer ) Render (ctx  * markup.RenderContext , input  io.Reader , output  io.Writer ) error  {
8181	tmpBlock  :=  bufio .NewWriter (output )
82+ 	maxSize  :=  setting .UI .CSV .MaxFileSize 
8283
83- 	// FIXME: don't read all to memory 
84- 	rawBytes , err  :=  io .ReadAll (input )
84+ 	if  maxSize  ==  0  {
85+ 		return  r .tableRender (ctx , input , tmpBlock )
86+ 	}
87+ 
88+ 	rawBytes , err  :=  io .ReadAll (io .LimitReader (input , maxSize + 1 ))
8589	if  err  !=  nil  {
8690		return  err 
8791	}
8892
89- 	if  setting .UI .CSV .MaxFileSize  !=  0  &&  setting .UI .CSV .MaxFileSize  <  int64 (len (rawBytes )) {
90- 		if  _ , err  :=  tmpBlock .WriteString ("<pre>" ); err  !=  nil  {
91- 			return  err 
92- 		}
93- 		if  _ , err  :=  tmpBlock .WriteString (html .EscapeString (string (rawBytes ))); err  !=  nil  {
94- 			return  err 
93+ 	if  int64 (len (rawBytes )) <=  maxSize  {
94+ 		return  r .tableRender (ctx , bytes .NewReader (rawBytes ), tmpBlock )
95+ 	}
96+ 	return  r .fallbackRender (io .MultiReader (bytes .NewReader (rawBytes ), input ), tmpBlock )
97+ }
98+ 
99+ func  (Renderer ) fallbackRender (input  io.Reader , tmpBlock  * bufio.Writer ) error  {
100+ 	_ , err  :=  tmpBlock .WriteString ("<pre>" )
101+ 	if  err  !=  nil  {
102+ 		return  err 
103+ 	}
104+ 
105+ 	scan  :=  bufio .NewScanner (input )
106+ 	scan .Split (bufio .ScanRunes )
107+ 	for  scan .Scan () {
108+ 		switch  scan .Text () {
109+ 		case  `&` :
110+ 			_ , err  =  tmpBlock .WriteString ("&" )
111+ 		case  `'` :
112+ 			_ , err  =  tmpBlock .WriteString ("'" ) // "'" is shorter than "'" and apos was not in HTML until HTML5. 
113+ 		case  `<` :
114+ 			_ , err  =  tmpBlock .WriteString ("<" )
115+ 		case  `>` :
116+ 			_ , err  =  tmpBlock .WriteString (">" )
117+ 		case  `"` :
118+ 			_ , err  =  tmpBlock .WriteString (""" ) // """ is shorter than """. 
119+ 		default :
120+ 			_ , err  =  tmpBlock .Write (scan .Bytes ())
95121		}
96- 		if  _ ,  err   :=   tmpBlock . WriteString ( "</pre>" );  err  !=  nil  {
122+ 		if  err  !=  nil  {
97123			return  err 
98124		}
99- 		return  tmpBlock .Flush ()
100125	}
101126
102- 	rd , err  :=  csv .CreateReaderAndDetermineDelimiter (ctx , bytes .NewReader (rawBytes ))
127+ 	_ , err  =  tmpBlock .WriteString ("</pre>" )
128+ 	if  err  !=  nil  {
129+ 		return  err 
130+ 	}
131+ 	return  tmpBlock .Flush ()
132+ }
133+ 
134+ func  (Renderer ) tableRender (ctx  * markup.RenderContext , input  io.Reader , tmpBlock  * bufio.Writer ) error  {
135+ 	rd , err  :=  csv .CreateReaderAndDetermineDelimiter (ctx , input )
103136	if  err  !=  nil  {
104137		return  err 
105138	}
0 commit comments