Saved views: a name cut after a space answers a server error, and re-saving the newest view says it needs a name #507
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#507
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, readingtable_viewsand runningsave_viewwith the snapshot's interpreter.Checked again on 2026-10-01 against
mainat0a5cad587: still present.table_viewsdecides whether a view was saved by comparing settings before and after, and finds the saved view again by comparing names normalised differently from the stored ones. Both go wrong on ordinary input.core/views_tables.py:63-76,table_views;core/tables.py:389-392,Table.save_view;core/tables.py:214,View.from_stored.1. A long name can raise
StopIterationsave_viewstores" ".join(name.split())[:60], which ends in a space when the cut falls just after one.View.from_storedstrips it on reading, but line 75 looks forv.name == " ".join(title.split())[:60], unstripped, withnext()and no default. Checked: for a name of 59 letters, a space and three more letters, the stored name is the 59 letters and the comparison fails.next()raisesStopIteration, the request answers a 500, and because requests are atomic (ATOMIC_REQUESTS) the save is rolled back: the person sees an error page and has no view.2. Re-saving the newest view says it needs a name
saved == current(line 69) is the only test for "nothing was saved".save_viewremoves the view with the same slug and appends the new one at the end, so re-saving the most recently saved view with the same name, query and columns gives an identical dictionary. Checked:save_view(cur, "Waiting", "q=acme", ["name"]) == curisTruewhen Waiting is the last view. The person is told "A view needs a name." about a view that has one.save_view, asname = " ".join((name or "").split())[:60].strip(), and havesave_viewreturn the slug it stored (or have the view compute the slug the same way), then find the view by slug withnext(..., None). Decide "no name" from the cleaned name or slug being empty, not from the settings being unchanged; an unchanged re-save answers "View saved." and redirects to the view.Related to #259 (closed), which added saved views.
Done when
tests/test_saved_views.pyhas tests that POSTing a 64-character name whose 60th character is a space tocore:table_viewsredirects to the view rather than answering 500, and that saving the same view twice in a row answers "View saved." both times.