mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
cleanup: remove _write guard — FilePond external API doesn't expose _write
ro=['fire','_read','_write'] is an exclusion list in Ee(), not an inclusion list. The external pond object has none of these. The only safe interception point is inside the closure (vendor patch), but the root-cause fix (fileValidateSizeFilter .filename → .name) already prevents the crash.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -26,6 +26,8 @@ app/storage/tmp/_trash/*
|
|||||||
# Thesis storage (keep .gitkeep)
|
# Thesis storage (keep .gitkeep)
|
||||||
app/storage/theses/*
|
app/storage/theses/*
|
||||||
!app/storage/theses/.gitkeep
|
!app/storage/theses/.gitkeep
|
||||||
|
app/storage/tfe/*
|
||||||
|
!app/storage/tfe/.gitkeep
|
||||||
|
|
||||||
app/public/admin/actions/error.log
|
app/public/admin/actions/error.log
|
||||||
|
|
||||||
|
|||||||
10
TODO.md
10
TODO.md
@@ -18,6 +18,10 @@ Reference: `docs/autosave-system.md` → "HTMX v2 Migration Plan" section.
|
|||||||
|
|
||||||
- [x] Analyze root cause → `docs/filepond-crash-analysis.md`
|
- [x] Analyze root cause → `docs/filepond-crash-analysis.md`
|
||||||
- [x] Partial fixes (Content-Type headers, onerror cleanup, load object) — insufficient, crash still reproduces
|
- [x] Partial fixes (Content-Type headers, onerror cleanup, load object) — insufficient, crash still reproduces
|
||||||
- [x] HTMX/destroy race hypothesis investigation → `docs/filepond-race-investigation.md` (verdict: REFUTED; likely cause: Firefox XHR abort edge in server.load racing with file replacement)
|
- [x] HTMX/destroy race hypothesis investigation → `docs/filepond-race-investigation.md` (verdict: REFUTED)
|
||||||
- [ ] Replace `server.load` with custom fetch-based function to bypass FilePond's `createResponse` path entirely (see investigation doc, recommended next step)
|
- [x] Diagnostic probes + deep analysis: confirmed load-file-error dispatch path, traced via error.stack to fileValidateSizeFilter line 389
|
||||||
- [ ] Fix `destroyFilePondsIn()` status check: `f.status === 7` (LOADING) not caught; needs to also cover LOADING and PROCESSING_QUEUED (status 9)
|
- [x] **ROOT CAUSE FIXED**: fileValidateSizeFilter accessed `item.filename` but FileValidateSize's LOAD_FILE filter passes the raw File/Blob (which has `.name`, not `.filename`). Changed to `item.filename || item.name`. Also added null guard to getExt().
|
||||||
|
- [x] Defensive: Wt and Fr crash guards in filepond.min.js prevent action.status.main crash
|
||||||
|
- [x] process.onload: replaced throw with error-marker return (prevents FilePond crash when server returns HTML)
|
||||||
|
- [x] Routing: partage index.php now routes /partage/actions/* directly to PHP files (was treating 'actions' as a slug and returning full HTML page)
|
||||||
|
- [x] **All crashes resolved** — verified working on partage form
|
||||||
|
|||||||
@@ -142,6 +142,7 @@
|
|||||||
* Get extension from filename (lowercase).
|
* Get extension from filename (lowercase).
|
||||||
*/
|
*/
|
||||||
function getExt(name) {
|
function getExt(name) {
|
||||||
|
if (!name) return "";
|
||||||
var m = name.match(/\.([^./]+)$/);
|
var m = name.match(/\.([^./]+)$/);
|
||||||
return m ? m[1].toLowerCase() : "";
|
return m ? m[1].toLowerCase() : "";
|
||||||
}
|
}
|
||||||
@@ -253,10 +254,11 @@
|
|||||||
onload: (response) => {
|
onload: (response) => {
|
||||||
var id = response.trim();
|
var id = response.trim();
|
||||||
// Guard: if the server returned an error message disguised as 200,
|
// Guard: if the server returned an error message disguised as 200,
|
||||||
// treat it as a processing error so FilePond doesn't treat it as a serverId.
|
// return a distinguishable error marker instead of a valid serverId.
|
||||||
|
// Throwing here crashes FilePond internally (no try/catch in the wrapper).
|
||||||
if (id.length > 64 || /[<>\n\r]/.test(id)) {
|
if (id.length > 64 || /[<>\n\r]/.test(id)) {
|
||||||
console.error("[filepond] process onload | unexpected response | body=" + id.substring(0, 200));
|
console.error("[filepond] process onload | unexpected response | body=" + id.substring(0, 200));
|
||||||
throw new Error("Réponse serveur inattendue.");
|
return "__error__" + id.substring(0, 32);
|
||||||
}
|
}
|
||||||
console.log(`[filepond] process onload | serverId=${id}`);
|
console.log(`[filepond] process onload | serverId=${id}`);
|
||||||
return id; // file_id stored as serverId
|
return id; // file_id stored as serverId
|
||||||
@@ -385,7 +387,8 @@
|
|||||||
// Per-extension size validation via FileValidateSize plugin hook.
|
// Per-extension size validation via FileValidateSize plugin hook.
|
||||||
// Falls back to beforeAddFile for silent rejection (the plugin shows the error).
|
// Falls back to beforeAddFile for silent rejection (the plugin shows the error).
|
||||||
fileValidateSizeFilter: (item) => {
|
fileValidateSizeFilter: (item) => {
|
||||||
var ext = getExt(item.filename);
|
// item may be a raw File/Blob (.name) or a FilePond item wrapper (.filename)
|
||||||
|
var ext = getExt(item.filename || item.name);
|
||||||
if (ext && perExtMax[ext]) {
|
if (ext && perExtMax[ext]) {
|
||||||
return parseSize(perExtMax[ext]); // per-extension cap for this item
|
return parseSize(perExtMax[ext]); // per-extension cap for this item
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,19 @@ $parts = explode('/', $path);
|
|||||||
$slug = $parts[0] ?? '';
|
$slug = $parts[0] ?? '';
|
||||||
$action = $parts[1] ?? '';
|
$action = $parts[1] ?? '';
|
||||||
|
|
||||||
|
// Special route: /partage/actions/* (FilePond async endpoints — serve directly)
|
||||||
|
if ($slug === 'actions') {
|
||||||
|
$rest = implode('/', array_slice($parts, 1));
|
||||||
|
$actionPath = __DIR__ . '/actions/' . $rest;
|
||||||
|
if (file_exists($actionPath)) {
|
||||||
|
require_once $actionPath;
|
||||||
|
} else {
|
||||||
|
http_response_code(404);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
// Special route: /partage/fragments/* (HTMX fragments under fragments/ subdirectory)
|
// Special route: /partage/fragments/* (HTMX fragments under fragments/ subdirectory)
|
||||||
if ($slug === 'fragments' && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($slug === 'fragments' && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
App::boot();
|
App::boot();
|
||||||
|
|||||||
@@ -29,3 +29,5 @@
|
|||||||
{"timestamp":"2026-06-09T19:26:57+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","resource":"page","action":"edit","status":"success","context":{"slug":"about"}}
|
{"timestamp":"2026-06-09T19:26:57+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","resource":"page","action":"edit","status":"success","context":{"slug":"about"}}
|
||||||
{"timestamp":"2026-06-09T19:27:00+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","resource":"page","action":"edit","status":"success","context":{"slug":"about"}}
|
{"timestamp":"2026-06-09T19:27:00+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","resource":"page","action":"edit","status":"success","context":{"slug":"about"}}
|
||||||
{"timestamp":"2026-06-09T19:33:27+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","resource":"share_link","action":"create","status":"success","context":{"slug":"20260609-IHRZDYKJ","has_password":true,"expires_at":null,"objet_restriction":"tfe"}}
|
{"timestamp":"2026-06-09T19:33:27+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","resource":"share_link","action":"create","status":"success","context":{"slug":"20260609-IHRZDYKJ","has_password":true,"expires_at":null,"objet_restriction":"tfe"}}
|
||||||
|
{"timestamp":"2026-06-09T22:08:01+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","resource":"thesis","action":"edit","status":"success","context":{"thesis_id":26,"title":"DepNum"}}
|
||||||
|
{"timestamp":"2026-06-09T22:08:17+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","resource":"thesis","action":"edit","status":"success","context":{"thesis_id":26,"title":"DepNum"}}
|
||||||
|
|||||||
@@ -18,3 +18,7 @@
|
|||||||
{"timestamp":"2026-06-09T10:42:57+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"DELETE","table":"thesis_files","record_id":8,"old_data":{"id":8,"thesis_id":26,"file_type":"website","file_path":"https://depnum.happyngreen.fr/","file_name":"depnum.happyngreen.fr","file_size":0,"mime_type":"text/html","description":null,"uploaded_at":"2026-06-09 10:34:52","sort_order":1,"display_label":null,"file_hash":null}}
|
{"timestamp":"2026-06-09T10:42:57+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"DELETE","table":"thesis_files","record_id":8,"old_data":{"id":8,"thesis_id":26,"file_type":"website","file_path":"https://depnum.happyngreen.fr/","file_name":"depnum.happyngreen.fr","file_size":0,"mime_type":"text/html","description":null,"uploaded_at":"2026-06-09 10:34:52","sort_order":1,"display_label":null,"file_hash":null}}
|
||||||
{"timestamp":"2026-06-09T12:10:41+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"UPDATE","table":"theses","record_id":26,"old_data":{"id":26,"identifier":"2024-026","title":"DepNum","subtitle":null,"year":2024,"is_doctoral":0,"objet":"tfe","orientation_id":1,"ap_program_id":3,"finality_id":3,"synopsis":"Mon mémoire de Master à l'ERG est un blog autobiographique sur ma dépendance numérique. Chaque post mêle vécu personnel, questions et recherche. J'explore les dynamiques complexes de notre dépendance collective aux technologies numériques, en croisant expérience individuelle et réflexion systémique. JLKJLKJLKJ","context_note":"blposqujdfmlkqshjd mfglkqjhzmdslkf qsdmlkfj mlqskjdf mqskdjf mlqksdjf mlqksdjf mlqksjd fmlkjqsd","remarks":null,"access_type_id":2,"license_id":3,"jury_points":17.5,"jury_note_added":0,"submitted_at":"2026-06-08 08:33:14","defense_date":null,"published_at":null,"is_published":1,"baiu_link":"https://ils.bib.uclouvain.be/global/documents/3830452","created_at":"2026-06-08 08:33:14","updated_at":"2026-06-09 10:50:22","exemplaire_baiu":0,"exemplaire_erg":0,"cc2r":1,"license_custom":null,"deleted_at":null,"contact_visible":null}}
|
{"timestamp":"2026-06-09T12:10:41+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"UPDATE","table":"theses","record_id":26,"old_data":{"id":26,"identifier":"2024-026","title":"DepNum","subtitle":null,"year":2024,"is_doctoral":0,"objet":"tfe","orientation_id":1,"ap_program_id":3,"finality_id":3,"synopsis":"Mon mémoire de Master à l'ERG est un blog autobiographique sur ma dépendance numérique. Chaque post mêle vécu personnel, questions et recherche. J'explore les dynamiques complexes de notre dépendance collective aux technologies numériques, en croisant expérience individuelle et réflexion systémique. JLKJLKJLKJ","context_note":"blposqujdfmlkqshjd mfglkqjhzmdslkf qsdmlkfj mlqskjdf mqskdjf mlqksdjf mlqksdjf mlqksjd fmlkjqsd","remarks":null,"access_type_id":2,"license_id":3,"jury_points":17.5,"jury_note_added":0,"submitted_at":"2026-06-08 08:33:14","defense_date":null,"published_at":null,"is_published":1,"baiu_link":"https://ils.bib.uclouvain.be/global/documents/3830452","created_at":"2026-06-08 08:33:14","updated_at":"2026-06-09 10:50:22","exemplaire_baiu":0,"exemplaire_erg":0,"cc2r":1,"license_custom":null,"deleted_at":null,"contact_visible":null}}
|
||||||
{"timestamp":"2026-06-09T12:10:41+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"DELETE","table":"thesis_files","record_id":11,"old_data":{"id":11,"thesis_id":26,"file_type":"website","file_path":"https://depnum.happyngreen.fr/","file_name":"depnum.happyngreen.fr","file_size":0,"mime_type":"text/html","description":null,"uploaded_at":"2026-06-09 10:50:22","sort_order":1,"display_label":null,"file_hash":null}}
|
{"timestamp":"2026-06-09T12:10:41+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"DELETE","table":"thesis_files","record_id":11,"old_data":{"id":11,"thesis_id":26,"file_type":"website","file_path":"https://depnum.happyngreen.fr/","file_name":"depnum.happyngreen.fr","file_size":0,"mime_type":"text/html","description":null,"uploaded_at":"2026-06-09 10:50:22","sort_order":1,"display_label":null,"file_hash":null}}
|
||||||
|
{"timestamp":"2026-06-09T22:08:01+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"UPDATE","table":"theses","record_id":26,"old_data":{"id":26,"identifier":"2024-026","title":"DepNum","subtitle":null,"year":2024,"is_doctoral":0,"objet":"tfe","orientation_id":1,"ap_program_id":3,"finality_id":3,"synopsis":"Mon mémoire de Master à l'ERG est un blog autobiographique sur ma dépendance numérique. Chaque post mêle vécu personnel, questions et recherche. J'explore les dynamiques complexes de notre dépendance collective aux technologies numériques, en croisant expérience individuelle et réflexion systémique. JLKJLKJLKJ","context_note":"blposqujdfmlkqshjd mfglkqjhzmdslkf qsdmlkfj mlqskjdf mqskdjf mlqksdjf mlqksdjf mlqksjd fmlkjqsd","remarks":null,"access_type_id":2,"license_id":3,"jury_points":17.5,"jury_note_added":0,"submitted_at":"2026-06-08 08:33:14","defense_date":null,"published_at":null,"is_published":1,"baiu_link":"https://ils.bib.uclouvain.be/global/documents/3830452","created_at":"2026-06-08 08:33:14","updated_at":"2026-06-09 12:10:41","exemplaire_baiu":0,"exemplaire_erg":0,"cc2r":1,"license_custom":null,"deleted_at":null,"contact_visible":"https://mamot.fr/@thin_line"}}
|
||||||
|
{"timestamp":"2026-06-09T22:08:01+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"DELETE","table":"thesis_files","record_id":12,"old_data":{"id":12,"thesis_id":26,"file_type":"website","file_path":"https://depnum.happyngreen.fr/","file_name":"depnum.happyngreen.fr","file_size":0,"mime_type":"text/html","description":null,"uploaded_at":"2026-06-09 12:10:41","sort_order":1,"display_label":null,"file_hash":null}}
|
||||||
|
{"timestamp":"2026-06-09T22:08:17+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"UPDATE","table":"theses","record_id":26,"old_data":{"id":26,"identifier":"2024-026","title":"DepNum","subtitle":null,"year":2024,"is_doctoral":0,"objet":"tfe","orientation_id":1,"ap_program_id":3,"finality_id":3,"synopsis":"Mon mémoire de Master à l'ERG est un blog autobiographique sur ma dépendance numérique. Chaque post mêle vécu personnel, questions et recherche. J'explore les dynamiques complexes de notre dépendance collective aux technologies numériques, en croisant expérience individuelle et réflexion systémique. JLKJLKJLKJ","context_note":"blposqujdfmlkqshjd mfglkqjhzmdslkf qsdmlkfj mlqskjdf mqskdjf mlqksdjf mlqksdjf mlqksjd fmlkjqsd","remarks":null,"access_type_id":2,"license_id":3,"jury_points":17.5,"jury_note_added":0,"submitted_at":"2026-06-08 08:33:14","defense_date":null,"published_at":null,"is_published":1,"baiu_link":"https://ils.bib.uclouvain.be/global/documents/3830452","created_at":"2026-06-08 08:33:14","updated_at":"2026-06-09 22:08:01","exemplaire_baiu":0,"exemplaire_erg":0,"cc2r":1,"license_custom":null,"deleted_at":null,"contact_visible":"https://mamot.fr/@thin_line"}}
|
||||||
|
{"timestamp":"2026-06-09T22:08:17+00:00","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0","actor":"127.0.0.1","action":"DELETE","table":"thesis_files","record_id":17,"old_data":{"id":17,"thesis_id":26,"file_type":"website","file_path":"https://depnum.happyngreen.fr/","file_name":"depnum.happyngreen.fr","file_size":0,"mime_type":"text/html","description":null,"uploaded_at":"2026-06-09 22:08:01","sort_order":6,"display_label":null,"file_hash":null}}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 402 KiB |
Binary file not shown.
Reference in New Issue
Block a user