fix(backend): valid hx-target selector and reject NaN/Infinity chapter input

hx-target="#card-<key>" is an invalid CSS selector for any key containing
a colon (every real bookmark key is "<site>:<series_id>"), so htmx threw
before swapping and the favourite/delete/chapter-override controls were
dead in the browser. Switch to the attribute-selector form
[id='card-<key>'], which querySelectorAll accepts regardless of the id's
characters.

Also close a validation gap in uiChapter: strconv.ParseFloat accepts
"NaN"/"Infinity"/"-Inf" with err == nil, and every comparison against NaN
is false, so num < 0 let both through to last_chapter_num and permanently
broke HasNewChapter. Reject non-finite values explicitly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 23:19:16 +07:00
parent 2c3d687b6d
commit daec18546c
3 changed files with 42 additions and 5 deletions
+2 -1
View File
@@ -6,6 +6,7 @@ import (
"html/template"
"io/fs"
"log"
"math"
"net/http"
"strconv"
"strings"
@@ -266,7 +267,7 @@ func (h *webHandler) uiChapter(w http.ResponseWriter, r *http.Request) {
}
raw := strings.TrimSpace(r.PostFormValue("chapter"))
num, err := strconv.ParseFloat(raw, 64)
if err != nil || num < 0 {
if err != nil || num < 0 || math.IsNaN(num) || math.IsInf(num, 0) {
http.Error(w, "chapter must be a non-negative number", http.StatusBadRequest)
return
}