0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-07-13 03:38:42 +02:00

fix(util): reject invalid characters between time-estimate units (#38416)

### What / why

`TimeEstimateParse` (used by the issue time-estimate form) only checked
that the first token starts at the beginning of the string and the last
token ends at its end, but never checked the gaps between consecutive
tokens. Non-whitespace garbage embedded between two valid units was
silently dropped and the string accepted with a wrong value instead of
being reported as invalid.

Examples that were wrongly accepted before this change:

- `1h 2x 3m` → 3780s (parsed as 1h3m)
- `1h_2m`    → 3720s
- `1h,1m`    → 3660s

All three now return an "invalid time string" error, while valid inputs
such as `1h 1m 1s` and `1h1m1s` keep working.

### How

Reject any non-whitespace content between two matched units.

---------

Signed-off-by: TowyTowy <towy@airreps.link>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
TowyTowy 2026-07-12 15:38:34 +02:00 committed by GitHub
parent b998c3c1aa
commit d2bd1589fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 10 additions and 0 deletions

View File

@ -40,6 +40,7 @@ var timeStrGlobalVars = sync.OnceValue(func() *timeStrGlobalVarsType {
})
func TimeEstimateParse(timeStr string) (int64, error) {
timeStr = strings.TrimSpace(timeStr)
if timeStr == "" {
return 0, nil
}
@ -51,7 +52,13 @@ func TimeEstimateParse(timeStr string) (int64, error) {
if matches[0][0] != 0 || matches[len(matches)-1][1] != len(timeStr) {
return 0, fmt.Errorf("invalid time string: %s", timeStr)
}
prevEnd := 0
for _, match := range matches {
// only whitespace may separate two units, otherwise the string contains invalid content like "1h x 2m"
if strings.TrimSpace(timeStr[prevEnd:match[0]]) != "" {
return 0, fmt.Errorf("invalid time string: %s", timeStr)
}
prevEnd = match[1]
amount, err := strconv.ParseInt(timeStr[match[2]:match[3]], 10, 64)
if err != nil {
return 0, fmt.Errorf("invalid time string: %v", err)

View File

@ -22,6 +22,9 @@ func TestTimeStr(t *testing.T) {
{"1s", 1, false},
{"1h 1m 1s", 3600 + 60 + 1, false},
{"1d1x", 0, true},
{"1h 2x 3m", 0, true},
{"1h_2m", 0, true},
{"1h,1m", 0, true},
}
for _, test := range tests {
t.Run(test.input, func(t *testing.T) {