From 3c7a955f05ec4c29f3c4f7412c45129b74c33e5c Mon Sep 17 00:00:00 2001 From: Gusted Date: Mon, 18 Dec 2023 18:14:04 +0100 Subject: [PATCH] [GITEA] Fix NPE in `UsernameSubRoute` - Backport of #1981 - When the user is not found in `reloadparam`, early return when the user is not found to avoid calling `IsUserVisibleToViewer` which in turn avoids causing a NPE. - This fixes the case that a 500 error and 404 error is shown on the same page. - Add integration test for non-existant user RSS. - Regression by c6366089df8390bc1f017006caaf4d4c69825880 (cherry picked from commit f0e06962786ef8c417b0c6f07940c1909d3b91ba) (cherry picked from commit 75d806690875a4fc38eb1e3c904096be34657011) (cherry picked from commit 4d0a1e0637450865c7bbac69e42d92d63b95149c) (cherry picked from commit 5f40a485da1b2c5f129f32e2ddc2065e3ba9ccd0) (cherry picked from commit c4cb7812e39add6f7ff3d6f3f2d4e02c66435f0e) --- routers/web/user/home.go | 5 ++++- tests/integration/user_test.go | 29 +++++++++++++++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index ad24e6ff3c..f25f1fef92 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -841,12 +841,15 @@ func UsernameSubRoute(ctx *context.Context) { reloadParam := func(suffix string) (success bool) { ctx.SetParams("username", strings.TrimSuffix(username, suffix)) context_service.UserAssignmentWeb()(ctx) + if ctx.Written() { + return false + } // check view permissions if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) { ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name)) return false } - return !ctx.Written() + return true } switch { case strings.HasSuffix(username, ".png"): diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index d7fcad322e..cd067992a4 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -246,16 +246,25 @@ func testExportUserGPGKeys(t *testing.T, user, expected string) { } func TestGetUserRss(t *testing.T) { - user34 := "the_34-user.with.all.allowedChars" - req := NewRequestf(t, "GET", "/%s.rss", user34) - resp := MakeRequest(t, req, http.StatusOK) - if assert.EqualValues(t, "application/rss+xml;charset=utf-8", resp.Header().Get("Content-Type")) { - rssDoc := NewHTMLParser(t, resp.Body).Find("channel") - title, _ := rssDoc.ChildrenFiltered("title").Html() - assert.EqualValues(t, "Feed of "the_1-user.with.all.allowedChars"", title) - description, _ := rssDoc.ChildrenFiltered("description").Html() - assert.EqualValues(t, "<p dir="auto">some <a href="https://commonmark.org/" rel="nofollow">commonmark</a>!</p>\n", description) - } + defer tests.PrepareTestEnv(t)() + + t.Run("Normal", func(t *testing.T) { + user34 := "the_34-user.with.all.allowedChars" + req := NewRequestf(t, "GET", "/%s.rss", user34) + resp := MakeRequest(t, req, http.StatusOK) + if assert.EqualValues(t, "application/rss+xml;charset=utf-8", resp.Header().Get("Content-Type")) { + rssDoc := NewHTMLParser(t, resp.Body).Find("channel") + title, _ := rssDoc.ChildrenFiltered("title").Html() + assert.EqualValues(t, "Feed of "the_1-user.with.all.allowedChars"", title) + description, _ := rssDoc.ChildrenFiltered("description").Html() + assert.EqualValues(t, "<p dir="auto">some <a href="https://commonmark.org/" rel="nofollow">commonmark</a>!</p>\n", description) + } + }) + t.Run("Non-existent user", func(t *testing.T) { + session := loginUser(t, "user2") + req := NewRequestf(t, "GET", "/non-existent-user.rss") + session.MakeRequest(t, req, http.StatusNotFound) + }) } func TestListStopWatches(t *testing.T) {