Fix regex panic in task completion (v3.3.1)
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 41s

- Replace unsupported lookahead regex with manual string replacement
- Fix 502 error when completing tasks
- Update version to 3.3.1
This commit is contained in:
poignatov
2026-01-06 16:50:11 +03:00
parent b41f6e7cdc
commit db74626068
3 changed files with 27 additions and 9 deletions

View File

@@ -1 +1 @@
3.3.0
3.3.1

View File

@@ -7517,13 +7517,27 @@ func (a *App) completeTaskHandler(w http.ResponseWriter, r *http.Request) {
}
}
// Затем заменяем $0, $1, и т.д. (экранированные уже защищены маркерами)
// Используем регулярное выражение для поиска $N, где после N не идет еще одна цифра
for i := 0; i < 100; i++ {
// Ищем $N, где после N не идет еще одна цифра (чтобы не заменить $10 при поиске $1)
// Go regexp не поддерживает lookahead, поэтому заменяем с конца (от больших чисел к меньшим)
for i := 99; i >= 0; i-- {
if rewardStr, ok := rewardStrings[i]; ok {
// Паттерн: $N, где после N не идет еще одна цифра (чтобы не заменить $10 при поиске $1)
pattern := fmt.Sprintf(`\$%d(?!\d)`, i)
re := regexp.MustCompile(pattern)
result = re.ReplaceAllString(result, rewardStr)
searchStr := fmt.Sprintf("$%d", i)
// Ищем все вхождения с конца строки
for {
idx := strings.LastIndex(result, searchStr)
if idx == -1 {
break
}
// Проверяем, что после $N не идет еще одна цифра
afterIdx := idx + len(searchStr)
if afterIdx >= len(result) || result[afterIdx] < '0' || result[afterIdx] > '9' {
// Можно заменить
result = result[:idx] + rewardStr + result[afterIdx:]
} else {
// После $N идет еще цифра (например, $10), пропускаем
break
}
}
}
}
// Восстанавливаем экранированные доллары из временных маркеров
@@ -7657,7 +7671,11 @@ func (a *App) completeTaskHandler(w http.ResponseWriter, r *http.Request) {
// Если repetition_date установлен, вычисляем next_show_at
// Если repetition_period не установлен и repetition_date не установлен, помечаем задачу как удаленную
// Если repetition_period = "0 day" (или любое значение с 0), не обновляем last_completed_at
if repetitionDate.Valid && repetitionDate.String != "" {
// Проверяем наличие repetition_date (используем COALESCE, поэтому пустая строка означает отсутствие)
hasRepetitionDate := repetitionDate.Valid && strings.TrimSpace(repetitionDate.String) != ""
if hasRepetitionDate {
// Есть repetition_date - вычисляем следующую дату показа
nextShowAt := calculateNextShowAtFromRepetitionDate(repetitionDate.String, time.Now())
if nextShowAt != nil {

View File

@@ -1,6 +1,6 @@
{
"name": "play-life-web",
"version": "3.3.0",
"version": "3.3.1",
"type": "module",
"scripts": {
"dev": "vite",