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
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:
@@ -7517,13 +7517,27 @@ func (a *App) completeTaskHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Затем заменяем $0, $1, и т.д. (экранированные уже защищены маркерами)
|
// Затем заменяем $0, $1, и т.д. (экранированные уже защищены маркерами)
|
||||||
// Используем регулярное выражение для поиска $N, где после N не идет еще одна цифра
|
// Ищем $N, где после N не идет еще одна цифра (чтобы не заменить $10 при поиске $1)
|
||||||
for i := 0; i < 100; i++ {
|
// Go regexp не поддерживает lookahead, поэтому заменяем с конца (от больших чисел к меньшим)
|
||||||
|
for i := 99; i >= 0; i-- {
|
||||||
if rewardStr, ok := rewardStrings[i]; ok {
|
if rewardStr, ok := rewardStrings[i]; ok {
|
||||||
// Паттерн: $N, где после N не идет еще одна цифра (чтобы не заменить $10 при поиске $1)
|
searchStr := fmt.Sprintf("$%d", i)
|
||||||
pattern := fmt.Sprintf(`\$%d(?!\d)`, i)
|
// Ищем все вхождения с конца строки
|
||||||
re := regexp.MustCompile(pattern)
|
for {
|
||||||
result = re.ReplaceAllString(result, rewardStr)
|
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_date установлен, вычисляем next_show_at
|
||||||
// Если repetition_period не установлен и repetition_date не установлен, помечаем задачу как удаленную
|
// Если repetition_period не установлен и repetition_date не установлен, помечаем задачу как удаленную
|
||||||
// Если repetition_period = "0 day" (или любое значение с 0), не обновляем last_completed_at
|
// Если 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 - вычисляем следующую дату показа
|
// Есть repetition_date - вычисляем следующую дату показа
|
||||||
nextShowAt := calculateNextShowAtFromRepetitionDate(repetitionDate.String, time.Now())
|
nextShowAt := calculateNextShowAtFromRepetitionDate(repetitionDate.String, time.Now())
|
||||||
if nextShowAt != nil {
|
if nextShowAt != nil {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "play-life-web",
|
"name": "play-life-web",
|
||||||
"version": "3.3.0",
|
"version": "3.3.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
Reference in New Issue
Block a user