@@ -50,12 +50,6 @@ const (
5050	tplMigrating     base.TplName  =  "repo/migrate/migrating" 
5151)
5252
53- type  namedBlob  struct  {
54- 	name       string 
55- 	isSymlink  bool 
56- 	blob       * git.Blob 
57- }
58- 
5953// locate a README for a tree in one of the supported paths. 
6054// 
6155// entries is passed to reduce calls to ListEntries(), so 
@@ -64,14 +58,14 @@ type namedBlob struct {
6458//	entries == ctx.Repo.Commit.SubTree(ctx.Repo.TreePath).ListEntries() 
6559// 
6660// FIXME: There has to be a more efficient way of doing this 
67- func  findReadmeFileInEntries (ctx  * context.Context , entries  []* git.TreeEntry ) (* namedBlob , error ) {
61+ func  findReadmeFileInEntries (ctx  * context.Context , entries  []* git.TreeEntry ) (string ,  * git. TreeEntry , error ) {
6862	// Create a list of extensions in priority order 
6963	// 1. Markdown files - with and without localisation - e.g. README.en-us.md or README.md 
7064	// 2. Txt files - e.g. README.txt 
7165	// 3. No extension - e.g. README 
7266	exts  :=  append (localizedExtensions (".md" , ctx .Language ()), ".txt" , "" ) // sorted by priority 
7367	extCount  :=  len (exts )
74- 	readmeFiles  :=  make ([]* namedBlob , extCount + 1 )
68+ 	readmeFiles  :=  make ([]* git. TreeEntry , extCount + 1 )
7569
7670	docsEntries  :=  make ([]* git.TreeEntry , 3 ) // (one of docs/, .gitea/ or .github/) 
7771	for  _ , entry  :=  range  entries  {
@@ -98,28 +92,21 @@ func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (*n
9892		}
9993		if  i , ok  :=  util .IsReadmeFileExtension (entry .Name (), exts ... ); ok  {
10094			log .Debug ("Potential readme file: %s" , entry .Name ())
101- 			if  readmeFiles [i ] ==  nil  ||  base .NaturalSortLess (readmeFiles [i ].name , entry .Blob ().Name ()) {
102- 				name  :=  entry .Name ()
103- 				isSymlink  :=  entry .IsLink ()
104- 				target  :=  entry 
105- 				if  isSymlink  {
106- 					var  err  error 
107- 					target , err  =  entry .FollowLinks ()
95+ 			if  readmeFiles [i ] ==  nil  ||  base .NaturalSortLess (readmeFiles [i ].Name (), entry .Blob ().Name ()) {
96+ 				if  entry .IsLink () {
97+ 					target , err  :=  entry .FollowLinks ()
10898					if  err  !=  nil  &&  ! git .IsErrBadLink (err ) {
109- 						return  nil , err 
110- 					}
111- 				}
112- 				if  target  !=  nil  &&  (target .IsExecutable () ||  target .IsRegular ()) {
113- 					readmeFiles [i ] =  & namedBlob {
114- 						name ,
115- 						isSymlink ,
116- 						target .Blob (),
99+ 						return  "" , nil , err 
100+ 					} else  if  target  !=  nil  &&  (target .IsExecutable () ||  target .IsRegular ()) {
101+ 						readmeFiles [i ] =  entry 
117102					}
103+ 				} else  {
104+ 					readmeFiles [i ] =  entry 
118105				}
119106			}
120107		}
121108	}
122- 	var  readmeFile  * namedBlob 
109+ 	var  readmeFile  * git. TreeEntry 
123110	for  _ , f  :=  range  readmeFiles  {
124111		if  f  !=  nil  {
125112			readmeFile  =  f 
@@ -140,20 +127,20 @@ func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (*n
140127			var  err  error 
141128			childEntries , err  :=  subTree .ListEntries ()
142129			if  err  !=  nil  {
143- 				return  nil , err 
130+ 				return  "" ,  nil , err 
144131			}
145- 			readmeFile , err  =  findReadmeFileInEntries (ctx , childEntries )
132+ 
133+ 			subfolder , readmeFile , err  :=  findReadmeFileInEntries (ctx , childEntries )
146134			if  err  !=  nil  &&  ! git .IsErrNotExist (err ) {
147- 				return  nil , err 
135+ 				return  "" ,  nil , err 
148136			}
149137			if  readmeFile  !=  nil  {
150- 				readmeFile .name  =  subTreeEntry .Name () +  "/"  +  readmeFile .name 
151- 				break 
138+ 				return  path .Join (subTreeEntry .Name (), subfolder ), readmeFile , nil 
152139			}
153140		}
154141	}
155142
156- 	return  readmeFile , nil 
143+ 	return  "" ,  readmeFile , nil 
157144}
158145
159146func  renderDirectory (ctx  * context.Context , treeLink  string ) {
@@ -177,16 +164,13 @@ func renderDirectory(ctx *context.Context, treeLink string) {
177164		return 
178165	}
179166
180- 	readmeFile , err  :=  findReadmeFileInEntries (ctx , entries )
167+ 	subfolder ,  readmeFile , err  :=  findReadmeFileInEntries (ctx , entries )
181168	if  err  !=  nil  {
182169		ctx .ServerError ("findReadmeFileInEntries" , err )
183170		return 
184171	}
185- 	if  readmeFile  ==  nil  {
186- 		return 
187- 	}
188172
189- 	renderReadmeFile (ctx , readmeFile ,  fmt . Sprintf ( "%s/%s" , treeLink ,  readmeFile . name ) )
173+ 	renderReadmeFile (ctx , subfolder ,  readmeFile , treeLink )
190174}
191175
192176// localizedExtensions prepends the provided language code with and without a 
@@ -270,25 +254,35 @@ func getFileReader(repoID int64, blob *git.Blob) ([]byte, io.ReadCloser, *fileIn
270254	return  buf , dataRc , & fileInfo {st .IsText (), true , meta .Size , & meta .Pointer , st }, nil 
271255}
272256
273- func  renderReadmeFile (ctx  * context.Context , readmeFile  * namedBlob , readmeTreelink  string ) {
257+ func  renderReadmeFile (ctx  * context.Context , subfolder  string , readmeFile  * git.TreeEntry , readmeTreelink  string ) {
258+ 	target  :=  readmeFile 
259+ 	if  readmeFile  !=  nil  &&  readmeFile .IsLink () {
260+ 		target , _  =  readmeFile .FollowLinks ()
261+ 	}
262+ 	if  target  ==  nil  {
263+ 		// if findReadmeFile() failed and/or gave us a broken symlink (which it shouldn't) 
264+ 		// simply skip rendering the README 
265+ 		return 
266+ 	}
267+ 
274268	ctx .Data ["RawFileLink" ] =  "" 
275269	ctx .Data ["ReadmeInList" ] =  true 
276270	ctx .Data ["ReadmeExist" ] =  true 
277- 	ctx .Data ["FileIsSymlink" ] =  readmeFile .isSymlink 
271+ 	ctx .Data ["FileIsSymlink" ] =  readmeFile .IsLink () 
278272
279- 	buf , dataRc , fInfo , err  :=  getFileReader (ctx .Repo .Repository .ID , readmeFile . blob )
273+ 	buf , dataRc , fInfo , err  :=  getFileReader (ctx .Repo .Repository .ID , target . Blob () )
280274	if  err  !=  nil  {
281275		ctx .ServerError ("getFileReader" , err )
282276		return 
283277	}
284278	defer  dataRc .Close ()
285279
286280	ctx .Data ["FileIsText" ] =  fInfo .isTextFile 
287- 	ctx .Data ["FileName" ] =  readmeFile .name 
281+ 	ctx .Data ["FileName" ] =  path . Join ( subfolder ,  readmeFile .Name ()) 
288282	ctx .Data ["IsLFSFile" ] =  fInfo .isLFSFile 
289283
290284	if  fInfo .isLFSFile  {
291- 		filenameBase64  :=  base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .name ))
285+ 		filenameBase64  :=  base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .Name () ))
292286		ctx .Data ["RawFileLink" ] =  fmt .Sprintf ("%s.git/info/lfs/objects/%s/%s" , ctx .Repo .Repository .Link (), url .PathEscape (fInfo .lfsMeta .Oid ), url .PathEscape (filenameBase64 ))
293287	}
294288
@@ -306,19 +300,19 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
306300
307301	rd  :=  charset .ToUTF8WithFallbackReader (io .MultiReader (bytes .NewReader (buf ), dataRc ))
308302
309- 	if  markupType  :=  markup .Type (readmeFile .name ); markupType  !=  ""  {
303+ 	if  markupType  :=  markup .Type (readmeFile .Name () ); markupType  !=  ""  {
310304		ctx .Data ["IsMarkup" ] =  true 
311305		ctx .Data ["MarkupType" ] =  markupType 
312306
313307		ctx .Data ["EscapeStatus" ], ctx .Data ["FileContent" ], err  =  markupRender (ctx , & markup.RenderContext {
314308			Ctx :          ctx ,
315- 			RelativePath : path .Join (ctx .Repo .TreePath , readmeFile .name ), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path). 
316- 			URLPrefix :    path .Dir (readmeTreelink ),
309+ 			RelativePath : path .Join (ctx .Repo .TreePath , readmeFile .Name () ), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path). 
310+ 			URLPrefix :    path .Join (readmeTreelink ,  subfolder ),
317311			Metas :        ctx .Repo .Repository .ComposeDocumentMetas (),
318312			GitRepo :      ctx .Repo .GitRepo ,
319313		}, rd )
320314		if  err  !=  nil  {
321- 			log .Error ("Render failed for %s in %-v: %v Falling back to rendering source" , readmeFile .name , ctx .Repo .Repository , err )
315+ 			log .Error ("Render failed for %s in %-v: %v Falling back to rendering source" , readmeFile .Name () , ctx .Repo .Repository , err )
322316			buf  :=  & bytes.Buffer {}
323317			ctx .Data ["EscapeStatus" ], _  =  charset .EscapeControlStringReader (rd , buf , ctx .Locale )
324318			ctx .Data ["FileContent" ] =  buf .String ()
0 commit comments