Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion models/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ func (repo *Repository) IsGenerated() bool {

// RepoPath returns repository path by given user and repository name.
func RepoPath(userName, repoName string) string { //revive:disable-line:exported
return filepath.Join(user_model.UserPath(userName), strings.ToLower(repoName)+".git")
return filepath.Join(setting.RepoRootPath, filepath.Clean(strings.ToLower(userName)), filepath.Clean(strings.ToLower(repoName)+".git"))
}

// RepoPath returns the repository path
Expand Down
2 changes: 1 addition & 1 deletion models/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ func GetInactiveUsers(ctx context.Context, olderThan time.Duration) ([]*User, er

// UserPath returns the path absolute path of user repositories.
func UserPath(userName string) string { //revive:disable-line:exported
return filepath.Join(setting.RepoRootPath, strings.ToLower(userName))
return filepath.Join(setting.RepoRootPath, filepath.Clean(strings.ToLower(userName)))
}

// GetUserByID returns the user object by given ID if exists.
Expand Down
16 changes: 5 additions & 11 deletions modules/auth/password/hash/argon2.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,11 @@ func NewArgon2Hasher(config string) *Argon2Hasher {
return nil
}

parsed, err := parseUIntParam(vals[0], "time", "argon2", config, nil)
hasher.time = uint32(parsed)

parsed, err = parseUIntParam(vals[1], "memory", "argon2", config, err)
hasher.memory = uint32(parsed)

parsed, err = parseUIntParam(vals[2], "threads", "argon2", config, err)
hasher.threads = uint8(parsed)

parsed, err = parseUIntParam(vals[3], "keyLen", "argon2", config, err)
hasher.keyLen = uint32(parsed)
var err error
hasher.time, err = parseUintParam[uint32](vals[0], "time", "argon2", config, nil)
hasher.memory, err = parseUintParam[uint32](vals[1], "memory", "argon2", config, err)
hasher.threads, err = parseUintParam[uint8](vals[2], "threads", "argon2", config, err)
hasher.keyLen, err = parseUintParam[uint32](vals[3], "keyLen", "argon2", config, err)
if err != nil {
return nil
}
Expand Down
8 changes: 5 additions & 3 deletions modules/auth/password/hash/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
)

func parseIntParam(value, param, algorithmName, config string, previousErr error) (int, error) {
Expand All @@ -18,11 +19,12 @@ func parseIntParam(value, param, algorithmName, config string, previousErr error
return parsed, previousErr // <- Keep the previous error as this function should still return an error once everything has been checked if any call failed
}

func parseUIntParam(value, param, algorithmName, config string, previousErr error) (uint64, error) { //nolint:unparam // algorithmName is always argon2
parsed, err := strconv.ParseUint(value, 10, 64)
func parseUintParam[T uint32 | uint8](value, param, algorithmName, config string, previousErr error) (ret T, _ error) {
_, isUint32 := any(ret).(uint32)
parsed, err := strconv.ParseUint(value, 10, util.Iif(isUint32, 32, 8))
if err != nil {
log.Error("invalid integer for %s representation in %s hash spec %s", param, algorithmName, config)
return 0, err
}
return parsed, previousErr // <- Keep the previous error as this function should still return an error once everything has been checked if any call failed
return T(parsed), previousErr // <- Keep the previous error as this function should still return an error once everything has been checked if any call failed
}
2 changes: 1 addition & 1 deletion modules/git/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func GetHook(repoPath, name string) (*Hook, error) {
}
h := &Hook{
name: name,
path: filepath.Join(repoPath, "hooks", name+".d", name),
path: filepath.Join(repoPath, filepath.Join("hooks", name+".d", name)),
}
isFile, err := util.IsFile(h.path)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion modules/setting/config_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func decodeEnvSectionKey(encoded string) (ok bool, section, key string) {
decodedBytes := make([]byte, len(toDecode)/2)
for i := 0; i < len(toDecode)/2; i++ {
// Can ignore error here as we know these should be hexadecimal from the regexp
byteInt, _ := strconv.ParseInt(toDecode[2*i:2*i+2], 16, 0)
byteInt, _ := strconv.ParseInt(toDecode[2*i:2*i+2], 16, 8)
decodedBytes[i] = byte(byteInt)
}
if inKey {
Expand Down
2 changes: 1 addition & 1 deletion modules/tempdir/tempdir.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type TempDir struct {
}

func (td *TempDir) JoinPath(elems ...string) string {
return filepath.Join(append([]string{td.base, td.sub}, elems...)...)
return filepath.Join(append([]string{td.base, td.sub}, filepath.Join(elems...))...)
}

// MkdirAllSub works like os.MkdirAll, but the base directory must exist
Expand Down
2 changes: 1 addition & 1 deletion modules/util/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func HexToRBGColor(colorString string) (float64, float64, float64) {
if len(hexString) == 8 {
hexString = hexString[0:6]
}
color, err := strconv.ParseUint(hexString, 16, 64)
color, err := strconv.ParseUint(hexString, 16, 32)
if err != nil {
return 0, 0, 0
}
Expand Down
27 changes: 11 additions & 16 deletions routers/web/repo/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,28 @@ func Activity(ctx *context.Context) {

ctx.Data["PageIsPulse"] = true

ctx.Data["Period"] = ctx.PathParam("period")

timeUntil := time.Now()
var timeFrom time.Time

switch ctx.Data["Period"] {
period, timeFrom := "weekly", timeUntil.Add(-time.Hour*168)
switch ctx.PathParam("period") {
case "daily":
timeFrom = timeUntil.Add(-time.Hour * 24)
period, timeFrom = "daily", timeUntil.Add(-time.Hour*24)
case "halfweekly":
timeFrom = timeUntil.Add(-time.Hour * 72)
period, timeFrom = "halfweekly", timeUntil.Add(-time.Hour*72)
case "weekly":
timeFrom = timeUntil.Add(-time.Hour * 168)
period, timeFrom = "weekly", timeUntil.Add(-time.Hour*168)
case "monthly":
timeFrom = timeUntil.AddDate(0, -1, 0)
period, timeFrom = "monthly", timeUntil.AddDate(0, -1, 0)
case "quarterly":
timeFrom = timeUntil.AddDate(0, -3, 0)
period, timeFrom = "quarterly", timeUntil.AddDate(0, -3, 0)
case "semiyearly":
timeFrom = timeUntil.AddDate(0, -6, 0)
period, timeFrom = "semiyearly", timeUntil.AddDate(0, -6, 0)
case "yearly":
timeFrom = timeUntil.AddDate(-1, 0, 0)
default:
ctx.Data["Period"] = "weekly"
timeFrom = timeUntil.Add(-time.Hour * 168)
period, timeFrom = "yearly", timeUntil.AddDate(-1, 0, 0)
}
ctx.Data["DateFrom"] = timeFrom
ctx.Data["DateUntil"] = timeUntil
ctx.Data["PeriodText"] = ctx.Tr("repo.activity.period." + ctx.Data["Period"].(string))
ctx.Data["Period"] = period
ctx.Data["PeriodText"] = ctx.Tr("repo.activity.period." + period)

canReadCode := ctx.Repo.CanRead(unit.TypeCode)
if canReadCode {
Expand Down
30 changes: 18 additions & 12 deletions routers/web/repo/githttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ func (h *serviceHandler) sendFile(ctx *context.Context, contentType, file string
ctx.Resp.WriteHeader(http.StatusBadRequest)
return
}
reqFile := filepath.Join(h.getRepoDir(), file)
reqFile := filepath.Join(h.getRepoDir(), filepath.Clean(file))

fi, err := os.Stat(reqFile)
if os.IsNotExist(err) {
Expand All @@ -395,13 +395,12 @@ func (h *serviceHandler) sendFile(ctx *context.Context, contentType, file string
var safeGitProtocolHeader = regexp.MustCompile(`^[0-9a-zA-Z]+=[0-9a-zA-Z]+(:[0-9a-zA-Z]+=[0-9a-zA-Z]+)*$`)

func prepareGitCmdWithAllowedService(service string) (*gitcmd.Command, error) {
if service == "receive-pack" {
return gitcmd.NewCommand("receive-pack"), nil
if service == ServiceTypeReceivePack {
return gitcmd.NewCommand(ServiceTypeReceivePack), nil
}
if service == "upload-pack" {
return gitcmd.NewCommand("upload-pack"), nil
if service == ServiceTypeUploadPack {
return gitcmd.NewCommand(ServiceTypeUploadPack), nil
}

return nil, fmt.Errorf("service %q is not allowed", service)
}

Expand Down Expand Up @@ -464,28 +463,35 @@ func serviceRPC(ctx *context.Context, h *serviceHandler, service string) {
}
}

const (
ServiceTypeUploadPack = "upload-pack"
ServiceTypeReceivePack = "receive-pack"
)

// ServiceUploadPack implements Git Smart HTTP protocol
func ServiceUploadPack(ctx *context.Context) {
h := httpBase(ctx)
if h != nil {
serviceRPC(ctx, h, "upload-pack")
serviceRPC(ctx, h, ServiceTypeUploadPack)
}
}

// ServiceReceivePack implements Git Smart HTTP protocol
func ServiceReceivePack(ctx *context.Context) {
h := httpBase(ctx)
if h != nil {
serviceRPC(ctx, h, "receive-pack")
serviceRPC(ctx, h, ServiceTypeReceivePack)
}
}

func getServiceType(ctx *context.Context) string {
serviceType := ctx.Req.FormValue("service")
if !strings.HasPrefix(serviceType, "git-") {
return ""
switch ctx.Req.FormValue("service") {
case "git-" + ServiceTypeUploadPack:
return ServiceTypeUploadPack
case "git-" + ServiceTypeReceivePack:
return ServiceTypeReceivePack
}
return strings.TrimPrefix(serviceType, "git-")
return ""
}

func updateServerInfo(ctx gocontext.Context, dir string) []byte {
Expand Down
14 changes: 14 additions & 0 deletions services/context/access_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
"text/template"
"time"
"unicode"

user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
Expand Down Expand Up @@ -37,6 +38,16 @@ const keyOfRequestIDInTemplate = ".RequestID"
// So, we accept a Request ID with a maximum character length of 40
const maxRequestIDByteLength = 40

func isSafeRequestID(id string) bool {
for _, r := range id {
safe := unicode.IsPrint(r)
if !safe {
return false
}
}
return true
}

func parseRequestIDFromRequestHeader(req *http.Request) string {
requestID := "-"
for _, key := range setting.Log.RequestIDHeaders {
Expand All @@ -45,6 +56,9 @@ func parseRequestIDFromRequestHeader(req *http.Request) string {
break
}
}
if !isSafeRequestID(requestID) {
return "-"
}
if len(requestID) > maxRequestIDByteLength {
requestID = requestID[:maxRequestIDByteLength] + "..."
}
Expand Down
5 changes: 5 additions & 0 deletions services/context/access_log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,8 @@ func TestAccessLogger(t *testing.T) {
recorder.record(time.Date(2000, 1, 2, 3, 4, 5, 0, time.UTC), &testAccessLoggerResponseWriterMock{}, req)
assert.Equal(t, []string{`remote-addr - - [02/Jan/2000:03:04:05 +0000] "GET /path https" 200 123123 "referer" "user-agent"`}, mockLogger.logs)
}

func TestAccessLoggerRequestID(t *testing.T) {
assert.False(t, isSafeRequestID("\x00"))
assert.True(t, isSafeRequestID("a b-c"))
}
2 changes: 1 addition & 1 deletion web_src/fomantic/build/components/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ $.fn.dropdown = function(parameters) {
moduleNamespace = 'module-' + namespace,

$module = $(this),
$context = $(settings.context),
$context = (typeof settings.context === 'string') ? $(document).find(settings.context) : $(settings.context), // GITEA-PATCH: use "jQuery.find(selector)" instead of "jQuery(selector)"
$text = $module.find(selector.text),
$search = $module.find(selector.search),
$sizer = $module.find(selector.sizer),
Expand Down
2 changes: 1 addition & 1 deletion web_src/fomantic/build/components/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ $.fn.modal = function(parameters) {
moduleNamespace = 'module-' + namespace,

$module = $(this),
$context = $(settings.context),
$context = (typeof settings.context === 'string') ? $(document).find(settings.context) : $(settings.context), // GITEA-PATCH: use "jQuery.find(selector)" instead of "jQuery(selector)"
$close = $module.find(selector.close),

$allModals,
Expand Down
2 changes: 1 addition & 1 deletion web_src/js/features/repo-issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ export function initRepoPullRequestReview() {
let ntr = tr.nextElementSibling;
if (!ntr?.classList.contains('add-comment')) {
ntr = createElementFromHTML(`
<tr class="add-comment" data-line-type="${lineType}">
<tr class="add-comment" data-line-type="${htmlEscape(lineType)}">
${isSplit ? `
<td class="add-comment-left" colspan="4"></td>
<td class="add-comment-right" colspan="4"></td>
Expand Down
5 changes: 4 additions & 1 deletion web_src/js/modules/fomantic/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ export function linkLabelAndInput(label: Element, input: Element) {
}
}

export const fomanticQuery = $;
export function fomanticQuery(s: string | Element | NodeListOf<Element>): ReturnType<typeof $> {
// intentionally make it only work for query selector, it isn't used for creating HTML elements (for safety)
return typeof s === 'string' ? $(document).find(s) : $(s);
}
7 changes: 6 additions & 1 deletion web_src/js/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ export function isDarkTheme(): boolean {

/** strip <tags> from a string */
export function stripTags(text: string): string {
return text.replace(/<[^>]*>?/g, '');
let prev = '';
while (prev !== text) {
prev = text;
text = text.replace(/<[^>]*>?/g, '');
}
return text;
}

export function parseIssueHref(href: string): IssuePathInfo {
Expand Down
Loading